فهرست منبع

import lm3s, lpc2148/lpc2478, x86/qemu, AT91SAM7S/7X, s3c44b0, STM32F103ZE bsp

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@4 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 16 سال پیش
والد
کامیت
99922cdf19
66فایلهای تغییر یافته به همراه14390 افزوده شده و 0 حذف شده
  1. 297 0
      libcpu/arm/AT91SAM7S/AT91SAM7S.h
  2. 94 0
      libcpu/arm/AT91SAM7S/context_gcc.S
  3. 107 0
      libcpu/arm/AT91SAM7S/context_rvds.S
  4. 42 0
      libcpu/arm/AT91SAM7S/cpu.c
  5. 91 0
      libcpu/arm/AT91SAM7S/interrupt.c
  6. 387 0
      libcpu/arm/AT91SAM7S/serial.c
  7. 56 0
      libcpu/arm/AT91SAM7S/serial.h
  8. 60 0
      libcpu/arm/AT91SAM7S/stack.c
  9. 237 0
      libcpu/arm/AT91SAM7S/start_gcc.S
  10. 498 0
      libcpu/arm/AT91SAM7S/start_rvds.S
  11. 40 0
      libcpu/arm/AT91SAM7S/trap.c
  12. 342 0
      libcpu/arm/AT91SAM7X/AT91SAM7X.h
  13. 99 0
      libcpu/arm/AT91SAM7X/context_gcc.S
  14. 107 0
      libcpu/arm/AT91SAM7X/context_rvds.S
  15. 42 0
      libcpu/arm/AT91SAM7X/cpu.c
  16. 91 0
      libcpu/arm/AT91SAM7X/interrupt.c
  17. 156 0
      libcpu/arm/AT91SAM7X/mii.h
  18. 554 0
      libcpu/arm/AT91SAM7X/sam7x_emac.c
  19. 64 0
      libcpu/arm/AT91SAM7X/sam7x_emac.h
  20. 396 0
      libcpu/arm/AT91SAM7X/serial.c
  21. 56 0
      libcpu/arm/AT91SAM7X/serial.h
  22. 60 0
      libcpu/arm/AT91SAM7X/stack.c
  23. 235 0
      libcpu/arm/AT91SAM7X/start_gcc.S
  24. 498 0
      libcpu/arm/AT91SAM7X/start_rvds.S
  25. 40 0
      libcpu/arm/AT91SAM7X/trap.c
  26. 67 0
      libcpu/arm/common/backtrace.c
  27. 4 0
      libcpu/arm/common/div0.c
  28. 393 0
      libcpu/arm/common/divsi3.S
  29. 42 0
      libcpu/arm/common/showmem.c
  30. 178 0
      libcpu/arm/lm3s/context_rvds.S
  31. 42 0
      libcpu/arm/lm3s/cpu.c
  32. 25 0
      libcpu/arm/lm3s/interrupt.c
  33. 42 0
      libcpu/arm/lm3s/kservice.c
  34. 362 0
      libcpu/arm/lm3s/serial.c
  35. 59 0
      libcpu/arm/lm3s/stack.c
  36. 251 0
      libcpu/arm/lm3s/start_rvds.S
  37. 393 0
      libcpu/arm/lpc214x/LPC214x.h
  38. 102 0
      libcpu/arm/lpc214x/context_gcc.S
  39. 107 0
      libcpu/arm/lpc214x/context_rvds.s
  40. 42 0
      libcpu/arm/lpc214x/cpu.c
  41. 105 0
      libcpu/arm/lpc214x/interrupt.c
  42. 387 0
      libcpu/arm/lpc214x/serial.c
  43. 61 0
      libcpu/arm/lpc214x/stack.c
  44. 508 0
      libcpu/arm/lpc214x/start_rvds.s
  45. 350 0
      libcpu/arm/lpc214x/startup_gcc.S
  46. 40 0
      libcpu/arm/lpc214x/trap.c
  47. 1201 0
      libcpu/arm/lpc24xx/LPC24xx.h
  48. 99 0
      libcpu/arm/lpc24xx/context_gcc.S
  49. 107 0
      libcpu/arm/lpc24xx/context_rvds.s
  50. 42 0
      libcpu/arm/lpc24xx/cpu.c
  51. 86 0
      libcpu/arm/lpc24xx/interrupt.c
  52. 149 0
      libcpu/arm/lpc24xx/serial.c
  53. 60 0
      libcpu/arm/lpc24xx/stack.c
  54. 214 0
      libcpu/arm/lpc24xx/start_gcc.S
  55. 1581 0
      libcpu/arm/lpc24xx/start_rvds.s
  56. 132 0
      libcpu/arm/lpc24xx/trap.c
  57. 99 0
      libcpu/arm/s3c44b0/context_gcc.S
  58. 107 0
      libcpu/arm/s3c44b0/context_rvds.s
  59. 122 0
      libcpu/arm/s3c44b0/cpu.c
  60. 148 0
      libcpu/arm/s3c44b0/interrupt.c
  61. 346 0
      libcpu/arm/s3c44b0/s3c44b0.h
  62. 118 0
      libcpu/arm/s3c44b0/serial.c
  63. 60 0
      libcpu/arm/s3c44b0/stack.c
  64. 257 0
      libcpu/arm/s3c44b0/start_gcc.S
  65. 1072 0
      libcpu/arm/s3c44b0/start_rvds.s
  66. 181 0
      libcpu/arm/s3c44b0/trap.c

+ 297 - 0
libcpu/arm/AT91SAM7S/AT91SAM7S.h

@@ -0,0 +1,297 @@
+/*
+ * File      : at91sam7s.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#ifndef __AT91SAM7S_H__
+#define __AT91SAM7S_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_REG *(volatile unsigned int *)		/* Hardware register definition */
+
+/* ========== Register definition for TC0 peripheral ==========  */
+#define AT91C_TC0_SR		(AT91_REG(0xFFFA0020)) /* TC0 Status Register */
+#define AT91C_TC0_RC		(AT91_REG(0xFFFA001C)) /* TC0 Register C */
+#define AT91C_TC0_RB		(AT91_REG(0xFFFA0018)) /* TC0 Register B */
+#define AT91C_TC0_CCR		(AT91_REG(0xFFFA0000)) /* TC0 Channel Control Register */
+#define AT91C_TC0_CMR		(AT91_REG(0xFFFA0004)) /* TC0 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC0_IER		(AT91_REG(0xFFFA0024)) /* TC0 Interrupt Enable Register */
+#define AT91C_TC0_RA		(AT91_REG(0xFFFA0014)) /* TC0 Register A */
+#define AT91C_TC0_IDR		(AT91_REG(0xFFFA0028)) /* TC0 Interrupt Disable Register */
+#define AT91C_TC0_CV		(AT91_REG(0xFFFA0010)) /* TC0 Counter Value */
+#define AT91C_TC0_IMR		(AT91_REG(0xFFFA002C)) /* TC0 Interrupt Mask Register */
+
+/* ========== Register definition for TC1 peripheral ========== */
+#define AT91C_TC1_RB		(AT91_REG(0xFFFA0058)) /* TC1 Register B */
+#define AT91C_TC1_CCR		(AT91_REG(0xFFFA0040)) /* TC1 Channel Control Register */
+#define AT91C_TC1_IER		(AT91_REG(0xFFFA0064)) /* TC1 Interrupt Enable Register */
+#define AT91C_TC1_IDR		(AT91_REG(0xFFFA0068)) /* TC1 Interrupt Disable Register */
+#define AT91C_TC1_SR		(AT91_REG(0xFFFA0060)) /* TC1 Status Register */
+#define AT91C_TC1_CMR		(AT91_REG(0xFFFA0044)) /* TC1 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC1_RA		(AT91_REG(0xFFFA0054)) /* TC1 Register A */
+#define AT91C_TC1_RC		(AT91_REG(0xFFFA005C)) /* TC1 Register C */
+#define AT91C_TC1_IMR		(AT91_REG(0xFFFA006C)) /* TC1 Interrupt Mask Register */
+#define AT91C_TC1_CV		(AT91_REG(0xFFFA0050)) /* TC1 Counter Value */
+
+/* ========== Register definition for TC2 peripheral ========== */
+#define AT91C_TC2_CMR		(AT91_REG(0xFFFA0084)) /* TC2 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC2_CCR		(AT91_REG(0xFFFA0080)) /* TC2 Channel Control Register */
+#define AT91C_TC2_CV		(AT91_REG(0xFFFA0090)) /* TC2 Counter Value */
+#define AT91C_TC2_RA		(AT91_REG(0xFFFA0094)) /* TC2 Register A */
+#define AT91C_TC2_RB		(AT91_REG(0xFFFA0098)) /* TC2 Register B */
+#define AT91C_TC2_IDR		(AT91_REG(0xFFFA00A8)) /* TC2 Interrupt Disable Register */
+#define AT91C_TC2_IMR		(AT91_REG(0xFFFA00AC)) /* TC2 Interrupt Mask Register */
+#define AT91C_TC2_RC		(AT91_REG(0xFFFA009C)) /* TC2 Register C */
+#define AT91C_TC2_IER		(AT91_REG(0xFFFA00A4)) /* TC2 Interrupt Enable Register */
+#define AT91C_TC2_SR		(AT91_REG(0xFFFA00A0)) /* TC2 Status Register */
+
+/* ========== Register definition for PITC peripheral ========== */
+#define AT91C_PITC_PIVR		(AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
+#define AT91C_PITC_PISR		(AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
+#define AT91C_PITC_PIIR		(AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
+#define AT91C_PITC_PIMR		(AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
+
+/* ========== Register definition for UDP peripheral ==========  */
+#define AT91C_UDP_NUM		(AT91_REG(0xFFFB0000)) /* UDP Frame Number Register */
+#define AT91C_UDP_STAT		(AT91_REG(0xFFFB0004)) /* UDP Global State Register */
+#define AT91C_UDP_FADDR		(AT91_REG(0xFFFB0008)) /* UDP Function Address Register */
+#define AT91C_UDP_IER		(AT91_REG(0xFFFB0010)) /* UDP Interrupt Enable Register */
+#define AT91C_UDP_IDR		(AT91_REG(0xFFFB0014)) /* UDP Interrupt Disable Register */
+#define AT91C_UDP_IMR		(AT91_REG(0xFFFB0018)) /* UDP Interrupt Mask Register */
+#define AT91C_UDP_ISR		(AT91_REG(0xFFFB001C)) /* UDP Interrupt Status Register */
+#define AT91C_UDP_ICR		(AT91_REG(0xFFFB0020)) /* UDP Interrupt Clear Register */
+#define AT91C_UDP_RSTEP		(AT91_REG(0xFFFB0028)) /* UDP Reset Endpoint Register */
+#define AT91C_UDP_CSR0		(AT91_REG(0xFFFB0030)) /* UDP Endpoint Control and Status Register */
+#define AT91C_UDP_CSR(n)	(*(&AT91C_UDP_CSR0 + n))
+#define AT91C_UDP_FDR0		(AT91_REG(0xFFFB0050)) /* UDP Endpoint FIFO Data Register */
+#define AT91C_UDP_FDR(n)	(*(&AT91C_UDP_FDR0 + n))
+#define AT91C_UDP_TXVC		(AT91_REG(0xFFFB0074)) /* UDP Transceiver Control Register */
+
+/* ========== Register definition for US0 peripheral ========== */
+#define AT91C_US0_CR		(AT91_REG(0xFFFC0000)) /* US0 Control Register */
+#define AT91C_US0_MR		(AT91_REG(0xFFFC0004)) /* US0 Mode Register */
+#define AT91C_US0_IER		(AT91_REG(0xFFFC0008)) /* US0 Interrupt Enable Register */
+#define AT91C_US0_IDR		(AT91_REG(0xFFFC000C)) /* US0 Interrupt Disable Register */
+#define AT91C_US0_IMR		(AT91_REG(0xFFFC0010)) /* US0 Interrupt Mask Register */
+#define AT91C_US0_CSR		(AT91_REG(0xFFFC0014)) /* US0 Channel Status Register */
+#define AT91C_US0_RHR		(AT91_REG(0xFFFC0018)) /* US0 Receiver Holding Register */
+#define AT91C_US0_THR		(AT91_REG(0xFFFC001C)) /* US0 Transmitter Holding Register */
+#define AT91C_US0_BRGR		(AT91_REG(0xFFFC0020)) /* US0 Baud Rate Generator Register */
+#define AT91C_US0_RTOR		(AT91_REG(0xFFFC0024)) /* US0 Receiver Time-out Register */
+#define AT91C_US0_TTGR		(AT91_REG(0xFFFC0028)) /* US0 Transmitter Time-guard Register */
+#define AT91C_US0_NER		(AT91_REG(0xFFFC0044)) /* US0 Nb Errors Register */
+#define AT91C_US0_FIDI		(AT91_REG(0xFFFC0040)) /* US0 FI_DI_Ratio Register */
+#define AT91C_US0_IF		(AT91_REG(0xFFFC004C)) /* US0 IRDA_FILTER Register */
+
+/* ========== Register definition for AIC peripheral ==========  */
+#define AT91C_AIC_SMR0		(AT91_REG(0xFFFFF000)) /* AIC Source Mode Register */
+#define AT91C_AIC_SMR(n)	(*(&AT91C_AIC_SMR0 + n))
+#define AT91C_AIC_SVR0		(AT91_REG(0xFFFFF080)) /* AIC Source Vector Register */
+#define AT91C_AIC_SVR(n)	(*(&AT91C_AIC_SVR0 + n))
+#define AT91C_AIC_IVR		(AT91_REG(0xFFFFF100)) /* AIC Interrupt Vector Register */
+#define AT91C_AIC_FVR		(AT91_REG(0xFFFFF104)) /* AIC FIQ Vector Register */
+#define AT91C_AIC_ISR		(AT91_REG(0xFFFFF108)) /* AIC Interrupt Status Register */
+#define AT91C_AIC_IPR		(AT91_REG(0xFFFFF10C)) /* AIC Interrupt Pending Register */
+#define AT91C_AIC_IMR		(AT91_REG(0xFFFFF110)) /* AIC Interrupt Mask Register */
+#define AT91C_AIC_CISR		(AT91_REG(0xFFFFF114)) /* AIC Core Interrupt Status Register */
+#define AT91C_AIC_IECR		(AT91_REG(0xFFFFF120)) /* AIC Interrupt Enable Command Register */
+#define AT91C_AIC_IDCR		(AT91_REG(0xFFFFF124)) /* AIC Interrupt Disable Command Register */
+#define AT91C_AIC_ICCR		(AT91_REG(0xFFFFF128)) /* AIC Interrupt Clear Command Register */
+#define AT91C_AIC_ISCR		(AT91_REG(0xFFFFF12C)) /* AIC Interrupt Set Command Register */
+#define AT91C_AIC_EOICR		(AT91_REG(0xFFFFF130)) /* AIC End of Interrupt Command Register */
+#define AT91C_AIC_SPU		(AT91_REG(0xFFFFF134)) /* AIC Spurious Vector Register */
+#define AT91C_AIC_DCR		(AT91_REG(0xFFFFF138)) /* AIC Debug Control Register (Protect) */
+#define AT91C_AIC_FFER		(AT91_REG(0xFFFFF140)) /* AIC Fast Forcing Enable Register */
+#define AT91C_AIC_FFDR		(AT91_REG(0xFFFFF144)) /* AIC Fast Forcing Disable Register */
+#define AT91C_AIC_FFSR		(AT91_REG(0xFFFFF148)) /* AIC Fast Forcing Status Register */
+
+
+/* ========== Register definition for DBGU peripheral ==========  */
+#define AT91C_DBGU_EXID		(AT91_REG(0xFFFFF244)) /* DBGU Chip ID Extension Register */
+#define AT91C_DBGU_BRGR		(AT91_REG(0xFFFFF220)) /* DBGU Baud Rate Generator Register */
+#define AT91C_DBGU_IDR		(AT91_REG(0xFFFFF20C)) /* DBGU Interrupt Disable Register */
+#define AT91C_DBGU_CSR		(AT91_REG(0xFFFFF214)) /* DBGU Channel Status Register */
+#define AT91C_DBGU_CIDR		(AT91_REG(0xFFFFF240)) /* DBGU Chip ID Register */
+#define AT91C_DBGU_MR		(AT91_REG(0xFFFFF204)) /* DBGU Mode Register */
+#define AT91C_DBGU_IMR		(AT91_REG(0xFFFFF210)) /* DBGU Interrupt Mask Register */
+#define AT91C_DBGU_CR		(AT91_REG(0xFFFFF200)) /* DBGU Control Register */
+#define AT91C_DBGU_FNTR		(AT91_REG(0xFFFFF248)) /* DBGU Force NTRST Register */
+#define AT91C_DBGU_THR		(AT91_REG(0xFFFFF21C)) /* DBGU Transmitter Holding Register */
+#define AT91C_DBGU_RHR		(AT91_REG(0xFFFFF218)) /* DBGU Receiver Holding Register */
+#define AT91C_DBGU_IER		(AT91_REG(0xFFFFF208)) /* DBGU Interrupt Enable Register */
+
+/* ========== Register definition for PIO peripheral ========== */
+#define AT91C_PIO_ODR		(AT91_REG(0xFFFFF414)) /* PIOA Output Disable Registerr */
+#define AT91C_PIO_SODR		(AT91_REG(0xFFFFF430)) /* PIOA Set Output Data Register */
+#define AT91C_PIO_ISR		(AT91_REG(0xFFFFF44C)) /* PIOA Interrupt Status Register */
+#define AT91C_PIO_ABSR		(AT91_REG(0xFFFFF478)) /* PIOA AB Select Status Register */
+#define AT91C_PIO_IER		(AT91_REG(0xFFFFF440)) /* PIOA Interrupt Enable Register */
+#define AT91C_PIO_PPUDR		(AT91_REG(0xFFFFF460)) /* PIOA Pull-up Disable Register */
+#define AT91C_PIO_IMR		(AT91_REG(0xFFFFF448)) /* PIOA Interrupt Mask Register */
+#define AT91C_PIO_PER		(AT91_REG(0xFFFFF400)) /* PIOA PIO Enable Register */
+#define AT91C_PIO_IFDR		(AT91_REG(0xFFFFF424)) /* PIOA Input Filter Disable Register */
+#define AT91C_PIO_OWDR		(AT91_REG(0xFFFFF4A4)) /* PIOA Output Write Disable Register */
+#define AT91C_PIO_MDSR		(AT91_REG(0xFFFFF458)) /* PIOA Multi-driver Status Register */
+#define AT91C_PIO_IDR		(AT91_REG(0xFFFFF444)) /* PIOA Interrupt Disable Register */
+#define AT91C_PIO_ODSR		(AT91_REG(0xFFFFF438)) /* PIOA Output Data Status Register */
+#define AT91C_PIO_PPUSR		(AT91_REG(0xFFFFF468)) /* PIOA Pull-up Status Register */
+#define AT91C_PIO_OWSR		(AT91_REG(0xFFFFF4A8)) /* PIOA Output Write Status Register */
+#define AT91C_PIO_BSR		(AT91_REG(0xFFFFF474)) /* PIOA Select B Register */
+#define AT91C_PIO_OWER		(AT91_REG(0xFFFFF4A0)) /* PIOA Output Write Enable Register */
+#define AT91C_PIO_IFER		(AT91_REG(0xFFFFF420)) /* PIOA Input Filter Enable Register */
+#define AT91C_PIO_PDSR		(AT91_REG(0xFFFFF43C)) /* PIOA Pin Data Status Register */
+#define AT91C_PIO_PPUER		(AT91_REG(0xFFFFF464)) /* PIOA Pull-up Enable Register */
+#define AT91C_PIO_OSR		(AT91_REG(0xFFFFF418)) /* PIOA Output Status Register */
+#define AT91C_PIO_ASR		(AT91_REG(0xFFFFF470)) /* PIOA Select A Register */
+#define AT91C_PIO_MDDR		(AT91_REG(0xFFFFF454)) /* PIOA Multi-driver Disable Register */
+#define AT91C_PIO_CODR		(AT91_REG(0xFFFFF434)) /* PIOA Clear Output Data Register */
+#define AT91C_PIO_MDER		(AT91_REG(0xFFFFF450)) /* PIOA Multi-driver Enable Register */
+#define AT91C_PIO_PDR		(AT91_REG(0xFFFFF404)) /* PIOA PIO Disable Register */
+#define AT91C_PIO_IFSR		(AT91_REG(0xFFFFF428)) /* PIOA Input Filter Status Register */
+#define AT91C_PIO_OER		(AT91_REG(0xFFFFF410)) /* PIOA Output Enable Register */
+#define AT91C_PIO_PSR		(AT91_REG(0xFFFFF408)) /* PIOA PIO Status Register */
+
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_IMR  	(AT91_REG(0xFFFFF448)) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_IER  	(AT91_REG(0xFFFFF440)) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_OWDR 	(AT91_REG(0xFFFFF4A4)) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_ISR  	(AT91_REG(0xFFFFF44C)) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_PPUDR 	(AT91_REG(0xFFFFF460)) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_MDSR 	(AT91_REG(0xFFFFF458)) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_MDER 	(AT91_REG(0xFFFFF450)) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PER  	(AT91_REG(0xFFFFF400)) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_PSR  	(AT91_REG(0xFFFFF408)) // (PIOA) PIO Status Register
+#define AT91C_PIOA_OER  	(AT91_REG(0xFFFFF410)) // (PIOA) Output Enable Register
+#define AT91C_PIOA_BSR  	(AT91_REG(0xFFFFF474)) // (PIOA) Select B Register
+#define AT91C_PIOA_PPUER 	(AT91_REG(0xFFFFF464)) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_MDDR 	(AT91_REG(0xFFFFF454)) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_PDR  	(AT91_REG(0xFFFFF404)) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_ODR  	(AT91_REG(0xFFFFF414)) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_IFDR 	(AT91_REG(0xFFFFF424)) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_ABSR 	(AT91_REG(0xFFFFF478)) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_ASR  	(AT91_REG(0xFFFFF470)) // (PIOA) Select A Register
+#define AT91C_PIOA_PPUSR 	(AT91_REG(0xFFFFF468)) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_ODSR 	(AT91_REG(0xFFFFF438)) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_SODR 	(AT91_REG(0xFFFFF430)) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_IFSR 	(AT91_REG(0xFFFFF428)) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_IFER 	(AT91_REG(0xFFFFF420)) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_OSR  	(AT91_REG(0xFFFFF418)) // (PIOA) Output Status Register
+#define AT91C_PIOA_IDR  	(AT91_REG(0xFFFFF444)) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_PDSR 	(AT91_REG(0xFFFFF43C)) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_CODR 	(AT91_REG(0xFFFFF434)) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_OWSR 	(AT91_REG(0xFFFFF4A8)) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_OWER 	(AT91_REG(0xFFFFF4A0)) // (PIOA) Output Write Enable Register
+// ========== Register definition for PIOB peripheral ==========
+#define AT91C_PIOB_OWSR 	(AT91_REG(0xFFFFF6A8)) // (PIOB) Output Write Status Register
+#define AT91C_PIOB_PPUSR 	(AT91_REG(0xFFFFF668)) // (PIOB) Pull-up Status Register
+#define AT91C_PIOB_PPUDR 	(AT91_REG(0xFFFFF660)) // (PIOB) Pull-up Disable Register
+#define AT91C_PIOB_MDSR 	(AT91_REG(0xFFFFF658)) // (PIOB) Multi-driver Status Register
+#define AT91C_PIOB_MDER 	(AT91_REG(0xFFFFF650)) // (PIOB) Multi-driver Enable Register
+#define AT91C_PIOB_IMR  	(AT91_REG(0xFFFFF648)) // (PIOB) Interrupt Mask Register
+#define AT91C_PIOB_OSR  	(AT91_REG(0xFFFFF618)) // (PIOB) Output Status Register
+#define AT91C_PIOB_OER  	(AT91_REG(0xFFFFF610)) // (PIOB) Output Enable Register
+#define AT91C_PIOB_PSR  	(AT91_REG(0xFFFFF608)) // (PIOB) PIO Status Register
+#define AT91C_PIOB_PER  	(AT91_REG(0xFFFFF600)) // (PIOB) PIO Enable Register
+#define AT91C_PIOB_BSR  	(AT91_REG(0xFFFFF674)) // (PIOB) Select B Register
+#define AT91C_PIOB_PPUER 	(AT91_REG(0xFFFFF664)) // (PIOB) Pull-up Enable Register
+#define AT91C_PIOB_IFDR 	(AT91_REG(0xFFFFF624)) // (PIOB) Input Filter Disable Register
+#define AT91C_PIOB_ODR  	(AT91_REG(0xFFFFF614)) // (PIOB) Output Disable Registerr
+#define AT91C_PIOB_ABSR 	(AT91_REG(0xFFFFF678)) // (PIOB) AB Select Status Register
+#define AT91C_PIOB_ASR  	(AT91_REG(0xFFFFF670)) // (PIOB) Select A Register
+#define AT91C_PIOB_IFER 	(AT91_REG(0xFFFFF620)) // (PIOB) Input Filter Enable Register
+#define AT91C_PIOB_IFSR 	(AT91_REG(0xFFFFF628)) // (PIOB) Input Filter Status Register
+#define AT91C_PIOB_SODR 	(AT91_REG(0xFFFFF630)) // (PIOB) Set Output Data Register
+#define AT91C_PIOB_ODSR 	(AT91_REG(0xFFFFF638)) // (PIOB) Output Data Status Register
+#define AT91C_PIOB_CODR 	(AT91_REG(0xFFFFF634)) // (PIOB) Clear Output Data Register
+#define AT91C_PIOB_PDSR 	(AT91_REG(0xFFFFF63C)) // (PIOB) Pin Data Status Register
+#define AT91C_PIOB_OWER 	(AT91_REG(0xFFFFF6A0)) // (PIOB) Output Write Enable Register
+#define AT91C_PIOB_IER  	(AT91_REG(0xFFFFF640)) // (PIOB) Interrupt Enable Register
+#define AT91C_PIOB_OWDR 	(AT91_REG(0xFFFFF6A4)) // (PIOB) Output Write Disable Register
+#define AT91C_PIOB_MDDR 	(AT91_REG(0xFFFFF654)) // (PIOB) Multi-driver Disable Register
+#define AT91C_PIOB_ISR  	(AT91_REG(0xFFFFF64C)) // (PIOB) Interrupt Status Register
+#define AT91C_PIOB_IDR  	(AT91_REG(0xFFFFF644)) // (PIOB) Interrupt Disable Register
+#define AT91C_PIOB_PDR  	(AT91_REG(0xFFFFF604)) // (PIOB) PIO Disable Register
+
+/* ========== Register definition for PMC peripheral ========== */
+#define AT91C_PMC_SCER		(AT91_REG(0xFFFFFC00)) /* PMC System Clock Enable Register */
+#define AT91C_PMC_SCDR		(AT91_REG(0xFFFFFC04)) /* PMC System Clock Disable Register */
+#define AT91C_PMC_SCSR		(AT91_REG(0xFFFFFC08)) /* PMC System Clock Status Register */
+#define AT91C_PMC_PCER		(AT91_REG(0xFFFFFC10)) /* PMC Peripheral Clock Enable Register */
+#define AT91C_PMC_PCDR		(AT91_REG(0xFFFFFC14)) /* PMC Peripheral Clock Disable Register */
+#define AT91C_PMC_PCSR		(AT91_REG(0xFFFFFC18)) /* PMC Peripheral Clock Status Register */
+#define AT91C_PMC_MOR		(AT91_REG(0xFFFFFC20)) /* PMC Main Oscillator Register */
+#define AT91C_PMC_MCFR		(AT91_REG(0xFFFFFC24)) /* PMC Main Clock  Frequency Register */
+#define AT91C_PMC_PLLR		(AT91_REG(0xFFFFFC2C)) /* PMC PLL Register */
+#define AT91C_PMC_MCKR		(AT91_REG(0xFFFFFC30)) /* PMC Master Clock Register */
+#define AT91C_PMC_PCKR		(AT91_REG(0xFFFFFC40)) /* PMC Programmable Clock Register */
+#define AT91C_PMC_IER		(AT91_REG(0xFFFFFC60)) /* PMC Interrupt Enable Register */
+#define AT91C_PMC_IDR		(AT91_REG(0xFFFFFC64)) /* PMC Interrupt Disable Register */
+#define AT91C_PMC_SR		(AT91_REG(0xFFFFFC68)) /* PMC Status Register */
+#define AT91C_PMC_IMR		(AT91_REG(0xFFFFFC6C)) /* PMC Interrupt Mask Register */
+
+/******************************************************************************/
+/*               PERIPHERAL ID DEFINITIONS FOR AT91SAM7S64                    */
+/******************************************************************************/
+#define AT91C_ID_FIQ    	0 	/* Advanced Interrupt Controller (FIQ) */
+#define AT91C_ID_SYS    	1 	/* System Peripheral */
+#define AT91C_ID_PIOA   	2 	/* Parallel IO Controller A */
+#define AT91C_ID_PIOB   	3 	/* Parallel IO Controller B */
+#define AT91C_ID_ADC    	4 	/* Analog-to-Digital Converter */
+#define AT91C_ID_SPI    	5	/* Serial Peripheral Interface */
+#define AT91C_ID_US0    	6	/* USART 0 */
+#define AT91C_ID_US1    	7	/* USART 1 */
+#define AT91C_ID_SSC    	8	/* Serial Synchronous Controller */
+#define AT91C_ID_TWI    	9 	/* Two-Wire Interface */
+#define AT91C_ID_PWMC   	10	/* PWM Controller */
+#define AT91C_ID_UDP    	11 	/* USB Device Port */
+#define AT91C_ID_TC0    	12 	/* Timer Counter 0 */
+#define AT91C_ID_TC1    	13 	/* Timer Counter 1 */
+#define AT91C_ID_TC2    	14 	/* Timer Counter 2 */
+#define AT91C_ID_15			15	/* Reserved */
+#define AT91C_ID_16 		16 	/* Reserved */
+#define AT91C_ID_17 		17 	/* Reserved */
+#define AT91C_ID_18 		18 	/* Reserved */
+#define AT91C_ID_19 		19 	/* Reserved */
+#define AT91C_ID_20 		20 	/* Reserved */
+#define AT91C_ID_21 		21 	/* Reserved */
+#define AT91C_ID_22 		22 	/* Reserved */
+#define AT91C_ID_23 		23 	/* Reserved */
+#define AT91C_ID_24 		24 	/* Reserved */
+#define AT91C_ID_25 		25 	/* Reserved */
+#define AT91C_ID_26 		26 	/* Reserved */
+#define AT91C_ID_27 		27 	/* Reserved */
+#define AT91C_ID_28 		28 	/* Reserved */
+#define AT91C_ID_29 		29 	/* Reserved */
+#define AT91C_ID_IRQ0		30 	/* Advanced Interrupt Controller (IRQ0) */
+#define AT91C_ID_IRQ1		31 	/* Advanced Interrupt Controller (IRQ1) */
+#define AT91C_ALL_INT		0xC0007FF7	/* ALL VALID INTERRUPTS */
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE			0x10
+#define FIQMODE				0x11
+#define IRQMODE				0x12
+#define SVCMODE				0x13
+#define ABORTMODE			0x17
+#define UNDEFMODE			0x1b
+#define MODEMASK			0x1f
+#define NOINT				0xc0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 94 - 0
libcpu/arm/AT91SAM7S/context_gcc.S

@@ -0,0 +1,94 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ */
+
+#define NOINT			0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable()/*
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level)/*
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)/*
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
+	stmfd	sp!, {r0-r12, lr}	/* push lr & register file */
+
+	mrs		r4, cpsr
+	stmfd	sp!, {r4}			/* push cpsr */
+	mrs		r4, spsr
+	stmfd	sp!, {r4}			/* push spsr */
+
+	str		sp, [r0]			/* store sp in preempted tasks TCB */
+	ldr		sp, [r1]			/* get new task stack pointer */
+
+	ldmfd	sp!, {r4}			/* pop new task spsr */
+	msr		spsr_cxsf, r4
+	ldmfd	sp!, {r4}			/* pop new task cpsr */
+	msr		cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to)/*
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr		sp, [r0]			/* get new task stack pointer */
+
+	ldmfd	sp!, {r4}			/* pop new task spsr */
+	msr		spsr_cxsf, r4
+	ldmfd	sp!, {r4}			/* pop new task cpsr */
+	msr		cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr		r2, =rt_thread_switch_interrput_flag
+	ldr		r3, [r2]
+	cmp		r3, #1
+	beq		_reswitch
+	mov		r3, #1							/* set rt_thread_switch_interrput_flag to 1 */
+	str		r3, [r2]
+	ldr		r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread */
+	str		r0, [r2]
+_reswitch:
+	ldr		r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread */
+	str		r1, [r2]
+	mov		pc, lr

+ 107 - 0
libcpu/arm/AT91SAM7S/context_rvds.S

@@ -0,0 +1,107 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-20     Bernard      first version
+; */
+
+NOINT	EQU		0xc0	; disable interrupt in psr
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	ARM
+	REQUIRE8
+	PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable	PROC
+	EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable	PROC
+	EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch	PROC
+	EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
+	STMFD	sp!, {r0-r12, lr}	; push lr & register file
+
+	MRS		r4, cpsr
+	STMFD	sp!, {r4}			; push cpsr
+	MRS		r4, spsr
+	STMFD	sp!, {r4}			; push spsr
+
+	STR	sp, [r0]				; store sp in preempted tasks TCB
+	LDR	sp, [r1]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to	PROC
+	EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt	PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]
+	CMP r3, #1
+	BEQ _reswitch
+	MOV r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR r3, [r2]
+	LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR r0, [r2]
+_reswitch
+	LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR r1, [r2]
+	BX	lr
+	ENDP
+
+	END

+ 42 - 0
libcpu/arm/AT91SAM7S/cpu.c

@@ -0,0 +1,42 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/

+ 91 - 0
libcpu/arm/AT91SAM7S/interrupt.c

@@ -0,0 +1,91 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+#define MAX_HANDLERS	32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	rt_base_t index;
+
+	for (index = 0; index < MAX_HANDLERS; index ++)
+	{
+		AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
+	}
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	/* disable interrupt */
+	AT91C_AIC_IDCR = 1 << vector;
+
+	/* clear interrupt */
+	AT91C_AIC_ICCR = 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	AT91C_AIC_IECR = 1 << vector;
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	if(vector >= 0 && vector < MAX_HANDLERS)
+	{
+		if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
+		if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
+	}
+}
+
+/*@}*/

+ 387 - 0
libcpu/arm/AT91SAM7S/serial.c

@@ -0,0 +1,387 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ * 2009-05-14     Bernard      add RT-THread device interface
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "AT91SAM7S.h"
+#include "serial.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+typedef volatile rt_uint32_t REG32;
+struct rt_at91serial_hw
+{
+	REG32	 US_CR; 	// Control Register
+	REG32	 US_MR; 	// Mode Register
+	REG32	 US_IER; 	// Interrupt Enable Register
+	REG32	 US_IDR; 	// Interrupt Disable Register
+	REG32	 US_IMR; 	// Interrupt Mask Register
+	REG32	 US_CSR; 	// Channel Status Register
+	REG32	 US_RHR; 	// Receiver Holding Register
+	REG32	 US_THR; 	// Transmitter Holding Register
+	REG32	 US_BRGR; 	// Baud Rate Generator Register
+	REG32	 US_RTOR; 	// Receiver Time-out Register
+	REG32	 US_TTGR; 	// Transmitter Time-guard Register
+	REG32	 Reserved0[5]; 	//
+	REG32	 US_FIDI; 	// FI_DI_Ratio Register
+	REG32	 US_NER; 	// Nb Errors Register
+	REG32	 Reserved1[1]; 	//
+	REG32	 US_IF; 	// IRDA_FILTER Register
+	REG32	 Reserved2[44]; 	//
+	REG32	 US_RPR; 	// Receive Pointer Register
+	REG32	 US_RCR; 	// Receive Counter Register
+	REG32	 US_TPR; 	// Transmit Pointer Register
+	REG32	 US_TCR; 	// Transmit Counter Register
+	REG32	 US_RNPR; 	// Receive Next Pointer Register
+	REG32	 US_RNCR; 	// Receive Next Counter Register
+	REG32	 US_TNPR; 	// Transmit Next Pointer Register
+	REG32	 US_TNCR; 	// Transmit Next Counter Register
+	REG32	 US_PTCR; 	// PDC Transfer Control Register
+	REG32	 US_PTSR; 	// PDC Transfer Status Register
+};
+
+struct rt_at91serial
+{
+	struct rt_device parent;
+
+	struct rt_at91serial_hw* hw_base;
+	rt_uint16_t peripheral_id;
+	rt_uint32_t baudrate;
+
+	/* reception field */
+	rt_uint16_t save_index, read_index;
+	rt_uint8_t  rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+#ifdef RT_USING_UART1
+struct rt_at91serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_at91serial serial2;
+#endif
+
+static void rt_hw_serial_isr(int irqno)
+{
+	rt_base_t level;
+	struct rt_device* device;
+	struct rt_at91serial* serial = RT_NULL;
+
+	if (irqno == AT91C_ID_US0)
+	{
+#ifdef RT_USING_UART1
+		/* serial 1 */
+		serial = &serial1;
+#endif
+	}
+	else if (irqno == AT91C_ID_US1)
+	{
+#ifdef RT_USING_UART2
+		/* serial 2 */
+		serial = &serial2;
+#endif
+	}
+	RT_ASSERT(serial != RT_NULL);
+
+	/* get generic device object */
+	device = (rt_device_t)serial;
+
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	/* get received character */
+	serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
+
+	/* move to next position */
+	serial->save_index ++;
+	if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+		serial->save_index = 0;
+
+	/* if the next position is read index, discard this 'read char' */
+	if (serial->save_index == serial->read_index)
+	{
+		serial->read_index ++;
+		if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+			serial->read_index = 0;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+
+	/* indicate to upper layer application */
+	if (device->rx_indicate != RT_NULL)
+		device->rx_indicate(device, 1);
+
+	/* ack interrupt */
+	AT91C_AIC_EOICR = 1;
+}
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	rt_uint32_t bd;
+	struct rt_at91serial* serial = (struct rt_at91serial*) dev;
+
+	RT_ASSERT(serial != RT_NULL);
+	/* must be US0 or US1 */
+	RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
+		(serial->peripheral_id != AT91C_ID_US1));
+
+	/* Enable Clock for USART */
+	AT91C_PMC_PCER = 1 << serial->peripheral_id;
+
+	/* Enable RxD0 and TxDO Pin */
+	if (serial->peripheral_id == AT91C_ID_US0)
+	{
+		/* set pinmux */
+		AT91C_PIO_PDR = (1 << 5) | (1 << 6);
+	}
+	else if (serial->peripheral_id == AT91C_ID_US1)
+	{
+		/* set pinmux */
+		AT91C_PIO_PDR = (1 << 21) | (1 << 22);
+	}
+
+	serial->hw_base->US_CR = AT91C_US_RSTRX	| 	/* Reset Receiver      */
+					AT91C_US_RSTTX		|		/* Reset Transmitter   */
+					AT91C_US_RXDIS		|		/* Receiver Disable    */
+					AT91C_US_TXDIS;				/* Transmitter Disable */
+
+	serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL |	/* Normal Mode */
+					AT91C_US_CLKS_CLOCK		|		/* Clock = MCK */
+					AT91C_US_CHRL_8_BITS	|		/* 8-bit Data  */
+					AT91C_US_PAR_NONE		|		/* No Parity   */
+					AT91C_US_NBSTOP_1_BIT;			/* 1 Stop Bit  */
+
+	/* set baud rate divisor */
+	bd =  ((MCK*10)/(serial->baudrate * 16));
+	if ((bd % 10) >= 5) bd = (bd / 10) + 1;
+	else bd /= 10;
+
+	serial->hw_base->US_BRGR = bd;
+	serial->hw_base->US_CR = AT91C_US_RXEN |		/* Receiver Enable     */
+					AT91C_US_TXEN;					/* Transmitter Enable  */
+
+	/* reset rx index */
+	serial->save_index = 0;
+	serial->read_index = 0;
+
+	/* reset rx buffer */
+	rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* enable UART rx interrupt */
+		serial->hw_base->US_IER = 1 << 0; 		/* RxReady interrupt */
+		serial->hw_base->US_IMR |= 1 << 0; 		/* umask RxReady interrupt */
+
+		/* install UART handler */
+		rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
+		AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
+		rt_hw_interrupt_umask(serial->peripheral_id);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* disable interrupt */
+		serial->hw_base->US_IDR = 1 << 0; 		/* RxReady interrupt */
+		serial->hw_base->US_IMR &= ~(1 << 0); 	/* mask RxReady interrupt */
+	}
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (serial->read_index != serial->save_index)
+			{
+				*ptr = serial->rx_buffer[serial->read_index];
+
+				serial->read_index ++;
+				if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					serial->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++; size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+	{
+		/* not support right now */
+		RT_ASSERT(0);
+	}
+	else
+	{
+		/* poll mode */
+		while (size)
+		{
+			/* Wait for Full Rx Buffer */
+			while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
+
+			/* Read Character */
+			*ptr = serial->hw_base->US_RHR;
+			ptr ++;
+			size --;
+		}
+
+		return (rt_size_t)ptr - (rt_size_t)buffer;
+	}
+
+	return 0;
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	ptr = (rt_uint8_t*) buffer;
+	if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+	{
+		if (dev->flag & RT_DEVICE_FLAG_STREAM)
+		{
+			/* it's a stream mode device */
+			while (size)
+			{
+				/* stream mode */
+				if (*ptr == '\n')
+				{
+					while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+					serial->hw_base->US_THR = '\r';
+				}
+
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+				/* Transmit Character */
+				serial->hw_base->US_THR = *ptr;
+				ptr ++; size --;
+			}
+		}
+		else
+		{
+			while (size)
+			{
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+				/* Transmit Character */
+				serial->hw_base->US_THR = *ptr;
+				ptr ++; size --;
+			}
+		}
+	}
+
+	return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	return RT_EOK;
+}
+
+rt_err_t rt_hw_serial_init()
+{
+	rt_device_t device;
+
+#ifdef RT_USING_UART1
+	device = (rt_device_t) &serial1;
+
+	/* init serial device private data */
+	serial1.hw_base 		= (struct rt_at91serial_hw*)AT91C_BASE_US0;
+	serial1.peripheral_id 	= AT91C_ID_US0;
+	serial1.baudrate		= 115200;
+
+	/* set device virtual interface */
+	device->init 	= rt_serial_init;
+	device->open 	= rt_serial_open;
+	device->close 	= rt_serial_close;
+	device->read 	= rt_serial_read;
+	device->write 	= rt_serial_write;
+	device->control = rt_serial_control;
+
+	/* register uart1 on device subsystem */
+	rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+	device = (rt_device_t) &serial2;
+
+	serial2.hw_base 		= (struct rt_at91serial_hw*)AT91C_BASE_US1;
+	serial2.peripheral_id 	= AT91C_ID_US1;
+	serial2.baudrate		= 115200;
+
+	/* set device virtual interface */
+	device->init 	= rt_serial_init;
+	device->open 	= rt_serial_open;
+	device->close 	= rt_serial_close;
+	device->read 	= rt_serial_read;
+	device->write 	= rt_serial_write;
+	device->control = rt_serial_control;
+
+	/* register uart2 on device subsystem */
+	rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+	return RT_EOK;
+}
+
+/*@}*/

+ 56 - 0
libcpu/arm/AT91SAM7S/serial.h

@@ -0,0 +1,56 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+
+#ifndef AT91C_BASE_US0
+#define AT91C_BASE_US0            (0xFFFC0000) // (US0) Base Address
+#endif
+
+#ifndef AT91C_BASE_US1
+#define AT91C_BASE_US1            (0xFFFC4000) // (US1) Base Address
+#endif
+
+#define AT91C_US_RXRDY			((unsigned int) 0x1 <<  0)	/* US RXRDY Interrupt */
+#define AT91C_US_TXRDY			((unsigned int) 0x1 <<  1)	/* US TXRDY Interrupt */
+#define AT91C_US_RSTRX			((unsigned int) 0x1 <<  2)	/* US Reset Receiver */
+#define AT91C_US_RSTTX			((unsigned int) 0x1 <<  3)	/* US Reset Transmitter */
+#define AT91C_US_RXEN			((unsigned int) 0x1 <<  4)	/* US Receiver Enable */
+#define AT91C_US_RXDIS			((unsigned int) 0x1 <<  5)	/* US Receiver Disable */
+#define AT91C_US_TXEN			((unsigned int) 0x1 <<  6)	/* US Transmitter Enable */
+#define AT91C_US_TXDIS			((unsigned int) 0x1 <<  7)	/* US Transmitter Disable */
+#define AT91C_US_RSTSTA			((unsigned int) 0x1 <<  8)	/* US Reset Status Bits */
+
+#define AT91C_US_USMODE_NORMAL	((unsigned int) 0x0)		/* USAR) Normal */
+#define AT91C_US_USMODE_RS485	((unsigned int) 0x1)		/* USAR) RS485 */
+#define AT91C_US_USMODE_HWHSH	((unsigned int) 0x2)		/* USAR) Hardware Handshaking */
+#define AT91C_US_USMODE_MODEM	((unsigned int) 0x3)		/* USAR) Modem */
+#define AT91C_US_USMODE_ISO7816_0	((unsigned int) 0x4)	/* USAR) ISO7816 protocol: T = 0 */
+#define AT91C_US_USMODE_ISO7816_1	((unsigned int) 0x6)	/* USAR) ISO7816 protocol: T = 1 */
+#define AT91C_US_USMODE_IRDA	((unsigned int) 0x8)		/* USAR) IrDA */
+#define AT91C_US_USMODE_SWHSH	((unsigned int) 0xC)		/* USAR) Software Handshaking */
+
+#define AT91C_US_CLKS_CLOCK		((unsigned int) 0x0 <<  4)	/* USAR) Clock */
+#define AT91C_US_CLKS_FDIV1		((unsigned int) 0x1 <<  4)	/* USAR) fdiv1 */
+#define AT91C_US_CLKS_SLOW		((unsigned int) 0x2 <<  4)	/* USAR) slow_clock (ARM) */
+#define AT91C_US_CLKS_EXT		((unsigned int) 0x3 <<  4)	/* USAR) External (SCK) */
+
+#define AT91C_US_CHRL_5_BITS	((unsigned int) 0x0 <<  6)	/* USAR) Character Length: 5 bits */
+#define AT91C_US_CHRL_6_BITS	((unsigned int) 0x1 <<  6)	/* USAR) Character Length: 6 bits */
+#define AT91C_US_CHRL_7_BITS	((unsigned int) 0x2 <<  6)	/* USAR) Character Length: 7 bits */
+#define AT91C_US_CHRL_8_BITS	((unsigned int) 0x3 <<  6)	/* USAR) Character Length: 8 bits */
+
+#define AT91C_US_PAR_EVEN		((unsigned int) 0x0 <<  9)	/* DBGU Even Parity */
+#define AT91C_US_PAR_ODD		((unsigned int) 0x1 <<  9)	/* DBGU Odd Parity */
+#define AT91C_US_PAR_SPACE		((unsigned int) 0x2 <<  9)	/* DBGU Parity forced to 0 (Space) */
+#define AT91C_US_PAR_MARK		((unsigned int) 0x3 <<  9)	/* DBGU Parity forced to 1 (Mark) */
+#define AT91C_US_PAR_NONE		((unsigned int) 0x4 <<  9)	/* DBGU No Parity */
+#define AT91C_US_PAR_MULTI_DROP	((unsigned int) 0x6 <<  9)	/* DBGU Multi-drop mode */
+
+#define AT91C_US_NBSTOP_1_BIT	((unsigned int) 0x0 << 12)	/* USART 1 stop bit */
+#define AT91C_US_NBSTOP_15_BIT	((unsigned int) 0x1 << 12)	/* USART Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits */
+#define AT91C_US_NBSTOP_2_BIT	((unsigned int) 0x2 << 12)	/* USART 2 stop bits */
+
+#define MCK		48054857
+#define BR    	115200			/* Baud Rate */
+#define BRD  	(MCK/16/BR)		/* Baud Rate Divisor */
+
+#endif

+ 60 - 0
libcpu/arm/AT91SAM7S/stack.c

@@ -0,0 +1,60 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      the first version
+ */
+#include <rtthread.h>
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk) 	 = (unsigned long)tentry;		/* entry point */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 237 - 0
libcpu/arm/AT91SAM7S/start_gcc.S

@@ -0,0 +1,237 @@
+/*
+ * File      : start_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-31     Bernard      first version
+ */
+
+	/* Internal Memory Base Addresses */
+	.equ    FLASH_BASE,     0x00100000   
+	.equ    RAM_BASE,       0x00200000
+
+	/* Stack Configuration */
+	.equ    TOP_STACK,      0x00204000
+	.equ    UND_STACK_SIZE, 0x00000100
+	.equ    SVC_STACK_SIZE, 0x00000400
+	.equ    ABT_STACK_SIZE, 0x00000100
+	.equ    FIQ_STACK_SIZE, 0x00000100
+	.equ    IRQ_STACK_SIZE, 0x00000100
+	.equ    USR_STACK_SIZE, 0x00000004
+
+	/* ARM architecture definitions */
+	.equ	MODE_USR, 0x10
+	.equ	MODE_FIQ, 0x11
+	.equ	MODE_IRQ, 0x12
+	.equ	MODE_SVC, 0x13
+	.equ	MODE_ABT, 0x17
+	.equ	MODE_UND, 0x1B
+	.equ	MODE_SYS, 0x1F
+
+	.equ    I_BIT, 0x80    /* when this bit is set, IRQ is disabled */
+	.equ    F_BIT, 0x40    /* when this bit is set, FIQ is disabled */
+
+.section .init, "ax"
+.code 32
+.align 0
+.globl _start
+_start:
+	b	reset
+	ldr	pc, _vector_undef
+	ldr	pc, _vector_swi
+	ldr	pc, _vector_pabt
+	ldr	pc, _vector_dabt
+	nop							/* reserved vector */
+	ldr	pc, _vector_irq
+	ldr	pc, _vector_fiq
+
+_vector_undef:	.word vector_undef
+_vector_swi:	.word vector_swi
+_vector_pabt:	.word vector_pabt
+_vector_dabt:	.word vector_dabt
+_vector_resv:	.word vector_resv
+_vector_irq:	.word vector_irq
+_vector_fiq:	.word vector_fiq
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start:	.word __bss_start
+.globl _bss_end
+_bss_end:	.word __bss_end
+
+/* the system entry */
+reset:
+	/* disable watchdog */
+	ldr r0, =0xFFFFFD40
+	ldr r1, =0x00008000
+	str r1, [r0, #0x04]
+	
+	/* enable the main oscillator */
+	ldr r0, =0xFFFFFC00
+	ldr r1, =0x00000601
+	str r1, [r0, #0x20]
+	
+	/* wait for main oscillator to stabilize */
+moscs_loop:
+	ldr r2, [r0, #0x68]
+	ands r2, r2, #1
+	beq moscs_loop
+	
+	/* set up the PLL */
+	ldr r1, =0x00191C05
+	str r1, [r0, #0x2C]
+	
+	/* wait for PLL to lock */
+pll_loop:
+	ldr r2, [r0, #0x68]
+	ands r2, r2, #0x04
+	beq pll_loop
+	
+	/* select clock */
+	ldr r1, =0x00000007
+	str r1, [r0, #0x30]
+	
+	/* setup stack for each mode */
+	ldr r0, =TOP_STACK
+	
+	/* set stack */
+	/* undefined instruction mode */
+	msr cpsr_c, #MODE_UND|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #UND_STACK_SIZE
+	
+	/* abort mode */
+	msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #ABT_STACK_SIZE
+	
+	/* FIQ mode */
+	msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #FIQ_STACK_SIZE
+	
+	/* IRQ mode */
+	msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #IRQ_STACK_SIZE
+	
+	/* supervisor mode */
+	msr cpsr_c, #MODE_SVC
+	mov sp, r0
+	
+#ifdef __FLASH_BUILD__
+	/* Relocate .data section (Copy from ROM to RAM) */
+	ldr     r1, =_etext
+	ldr     r2, =_data
+	ldr     r3, =_edata
+data_loop:
+	cmp     r2, r3
+	ldrlo   r0, [r1], #4
+	strlo   r0, [r2], #4
+	blo     data_loop
+#else
+	/* remap SRAM to 0x0000 */
+	ldr r0, =0xFFFFFF00
+	mov r1, #0x01
+	str r1, [r0]
+#endif
+	
+	/* mask all IRQs */
+	ldr	r1, =0xFFFFF124
+	ldr	r0, =0XFFFFFFFF
+	str	r0, [r1]
+	
+	/* start RT-Thread Kernel */
+	ldr	pc, _rtthread_startup
+	
+_rtthread_startup: .word rtthread_startup
+
+/* exception handlers */
+vector_undef: b	vector_undef
+vector_swi  : b vector_swi
+vector_pabt : b vector_pabt
+vector_dabt : b vector_dabt
+vector_resv : b vector_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+	stmfd	sp!, {r0-r12,lr}
+	bl	rt_interrupt_enter
+	bl	rt_hw_trap_irq
+	bl	rt_interrupt_leave
+
+	/* 
+	 * if rt_thread_switch_interrput_flag set, jump to
+	 * rt_hw_context_switch_interrupt_do and don't return
+	 */
+	ldr	r0, =rt_thread_switch_interrput_flag
+	ldr	r1, [r0]
+	cmp	r1, #1
+	beq	rt_hw_context_switch_interrupt_do
+
+	ldmfd	sp!, {r0-r12,lr}
+	subs	pc, lr, #4
+
+vector_fiq:
+	stmfd	sp!,{r0-r7,lr}
+	bl 	rt_hw_trap_fiq
+	ldmfd	sp!,{r0-r7,lr}
+	subs	pc,lr,#4
+
+/*
+ * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+ */
+rt_hw_context_switch_interrupt_do:
+	mov		r1,  #0				/* clear flag */
+	str		r1,  [r0]
+
+	ldmfd	sp!, {r0-r12,lr}	/* reload saved registers */
+	stmfd	sp!, {r0-r3}		/* save r0-r3 */
+	mov		r1,  sp
+	add		sp,  sp, #16		/* restore sp */
+	sub		r2,  lr, #4			/* save old task's pc to r2 */
+
+	mrs		r3,  spsr			/* disable interrupt */
+	orr		r0,  r3, #I_BIT|F_BIT
+	msr		spsr_c, r0
+
+	ldr		r0,  =.+8			/* switch to interrupted task's stack */
+	movs	pc,  r0
+
+	stmfd	sp!, {r2}			/* push old task's pc */
+	stmfd	sp!, {r4-r12,lr}	/* push old task's lr,r12-r4 */
+	mov		r4,  r1				/* Special optimised code below */
+	mov		r5,  r3
+	ldmfd	r4!, {r0-r3}
+	stmfd	sp!, {r0-r3}		/* push old task's r3-r0 */
+	stmfd	sp!, {r5}			/* push old task's psr */
+	mrs		r4,  spsr
+	stmfd	sp!, {r4}			/* push old task's spsr */
+
+	ldr		r4,  =rt_interrupt_from_thread
+	ldr		r5,  [r4]
+	str		sp,  [r5]			/* store sp in preempted tasks's TCB */
+
+	ldr		r6,  =rt_interrupt_to_thread
+	ldr		r6,  [r6]
+	ldr		sp,  [r6]			/* get new task's stack pointer */
+
+	ldmfd	sp!, {r4}			/* pop new task's spsr */
+	msr		SPSR_cxsf, r4
+	ldmfd	sp!, {r4}			/* pop new task's psr */
+	msr		CPSR_cxsf, r4
+
+	ldmfd	sp!, {r0-r12,lr,pc}	/* pop new task's r0-r12,lr & pc */

+ 498 - 0
libcpu/arm/AT91SAM7S/start_rvds.S

@@ -0,0 +1,498 @@
+;/*****************************************************************************/
+;/* SAM7.S: Startup file for Atmel AT91SAM7 device series                     */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>>                          */ 
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools.                   */
+;/* Copyright (c) 2005-2006 Keil Software. All rights reserved.               */
+;/* This software may only be used under the terms of a valid, current,       */
+;/* end user licence from KEIL for a compatible version of KEIL software      */
+;/* development tools. Nothing else gives you the right to use this software. */
+;/*****************************************************************************/
+
+
+;/*
+; *  The SAM7.S code is executed after CPU Reset. This file may be 
+; *  translated with the following SET symbols. In uVision these SET 
+; *  symbols are entered under Options - ASM - Define.
+; *
+; *  REMAP: when set the startup code remaps exception vectors from
+; *  on-chip RAM to address 0.
+; *
+; *  RAM_INTVEC: when set the startup code copies exception vectors 
+; *  from on-chip Flash to on-chip RAM.
+; */
+
+
+; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+
+Mode_USR        EQU     0x10
+Mode_FIQ        EQU     0x11
+Mode_IRQ        EQU     0x12
+Mode_SVC        EQU     0x13
+Mode_ABT        EQU     0x17
+Mode_UND        EQU     0x1B
+Mode_SYS        EQU     0x1F
+
+I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
+F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
+
+
+; Internal Memory Base Addresses
+FLASH_BASE      EQU     0x00100000   
+RAM_BASE        EQU     0x00200000
+
+
+;// <h> Stack Configuration (Stack Sizes in Bytes)
+;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
+;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
+;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
+;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
+;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
+;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
+;// </h>
+
+UND_Stack_Size  EQU     0x00000000
+SVC_Stack_Size  EQU     0x00000100
+ABT_Stack_Size  EQU     0x00000000
+FIQ_Stack_Size  EQU     0x00000000
+IRQ_Stack_Size  EQU     0x00000100
+USR_Stack_Size  EQU     0x00000100
+
+ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                         FIQ_Stack_Size + IRQ_Stack_Size)
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem       SPACE   USR_Stack_Size
+__initial_sp    SPACE   ISR_Stack_Size
+Stack_Top
+
+
+;// <h> Heap Configuration
+;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
+;// </h>
+
+Heap_Size       EQU     0x00000000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+; Reset Controller (RSTC) definitions
+RSTC_BASE       EQU     0xFFFFFD00      ; RSTC Base Address
+RSTC_MR         EQU     0x08            ; RSTC_MR Offset
+
+;/*
+;// <e> Reset Controller (RSTC)
+;//   <o1.0>     URSTEN: User Reset Enable
+;//              <i> Enables NRST Pin to generate Reset
+;//   <o1.8..11> ERSTL: External Reset Length <0-15>
+;//              <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
+;// </e>
+;*/
+RSTC_SETUP      EQU     1
+RSTC_MR_Val     EQU     0xA5000401
+
+
+; Embedded Flash Controller (EFC) definitions
+EFC_BASE        EQU     0xFFFFFF00      ; EFC Base Address
+EFC0_FMR        EQU     0x60            ; EFC0_FMR Offset
+EFC1_FMR        EQU     0x70            ; EFC1_FMR Offset
+
+;// <e> Embedded Flash Controller 0 (EFC0)
+;//   <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;//               <i> Number of Master Clock Cycles in 1us
+;//   <o1.8..9>   FWS: Flash Wait State
+;//               <0=> Read: 1 cycle / Write: 2 cycles
+;//               <1=> Read: 2 cycle / Write: 3 cycles
+;//               <2=> Read: 3 cycle / Write: 4 cycles
+;//               <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC0_SETUP      EQU     1
+EFC0_FMR_Val    EQU     0x00320100
+
+;// <e> Embedded Flash Controller 1 (EFC1)
+;//   <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;//               <i> Number of Master Clock Cycles in 1us
+;//   <o1.8..9>   FWS: Flash Wait State
+;//               <0=> Read: 1 cycle / Write: 2 cycles
+;//               <1=> Read: 2 cycle / Write: 3 cycles
+;//               <2=> Read: 3 cycle / Write: 4 cycles
+;//               <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC1_SETUP      EQU     0
+EFC1_FMR_Val    EQU     0x00320100
+
+
+; Watchdog Timer (WDT) definitions
+WDT_BASE        EQU     0xFFFFFD40      ; WDT Base Address
+WDT_MR          EQU     0x04            ; WDT_MR Offset
+
+;// <e> Watchdog Timer (WDT)
+;//   <o1.0..11>  WDV: Watchdog Counter Value <0-4095>
+;//   <o1.16..27> WDD: Watchdog Delta Value <0-4095>
+;//   <o1.12>     WDFIEN: Watchdog Fault Interrupt Enable
+;//   <o1.13>     WDRSTEN: Watchdog Reset Enable
+;//   <o1.14>     WDRPROC: Watchdog Reset Processor
+;//   <o1.28>     WDDBGHLT: Watchdog Debug Halt
+;//   <o1.29>     WDIDLEHLT: Watchdog Idle Halt
+;//   <o1.15>     WDDIS: Watchdog Disable
+;// </e>
+WDT_SETUP       EQU     1
+WDT_MR_Val      EQU     0x00008000
+
+
+; Power Mangement Controller (PMC) definitions
+PMC_BASE        EQU     0xFFFFFC00      ; PMC Base Address
+PMC_MOR         EQU     0x20            ; PMC_MOR Offset
+PMC_MCFR        EQU     0x24            ; PMC_MCFR Offset
+PMC_PLLR        EQU     0x2C            ; PMC_PLLR Offset
+PMC_MCKR        EQU     0x30            ; PMC_MCKR Offset
+PMC_SR          EQU     0x68            ; PMC_SR Offset
+PMC_MOSCEN      EQU     (1<<0)          ; Main Oscillator Enable
+PMC_OSCBYPASS   EQU     (1<<1)          ; Main Oscillator Bypass
+PMC_OSCOUNT     EQU     (0xFF<<8)       ; Main OScillator Start-up Time
+PMC_DIV         EQU     (0xFF<<0)       ; PLL Divider
+PMC_PLLCOUNT    EQU     (0x3F<<8)       ; PLL Lock Counter
+PMC_OUT         EQU     (0x03<<14)      ; PLL Clock Frequency Range
+PMC_MUL         EQU     (0x7FF<<16)     ; PLL Multiplier
+PMC_USBDIV      EQU     (0x03<<28)      ; USB Clock Divider
+PMC_CSS         EQU     (3<<0)          ; Clock Source Selection
+PMC_PRES        EQU     (7<<2)          ; Prescaler Selection
+PMC_MOSCS       EQU     (1<<0)          ; Main Oscillator Stable
+PMC_LOCK        EQU     (1<<2)          ; PLL Lock Status
+PMC_MCKRDY      EQU     (1<<3)          ; Master Clock Status
+
+;// <e> Power Mangement Controller (PMC)
+;//   <h> Main Oscillator
+;//     <o1.0>      MOSCEN: Main Oscillator Enable
+;//     <o1.1>      OSCBYPASS: Oscillator Bypass
+;//     <o1.8..15>  OSCCOUNT: Main Oscillator Startup Time <0-255>
+;//   </h>
+;//   <h> Phase Locked Loop (PLL)
+;//     <o2.0..7>   DIV: PLL Divider <0-255>
+;//     <o2.16..26> MUL: PLL Multiplier <0-2047>
+;//                 <i> PLL Output is multiplied by MUL+1
+;//     <o2.14..15> OUT: PLL Clock Frequency Range
+;//                 <0=> 80..160MHz  <1=> Reserved
+;//                 <2=> 150..220MHz <3=> Reserved
+;//     <o2.8..13>  PLLCOUNT: PLL Lock Counter <0-63>
+;//     <o2.28..29> USBDIV: USB Clock Divider
+;//                 <0=> None  <1=> 2  <2=> 4  <3=> Reserved
+;//   </h>
+;//   <o3.0..1>   CSS: Clock Source Selection
+;//               <0=> Slow Clock
+;//               <1=> Main Clock
+;//               <2=> Reserved
+;//               <3=> PLL Clock
+;//   <o3.2..4>   PRES: Prescaler
+;//               <0=> None
+;//               <1=> Clock / 2    <2=> Clock / 4
+;//               <3=> Clock / 8    <4=> Clock / 16
+;//               <5=> Clock / 32   <6=> Clock / 64
+;//               <7=> Reserved
+;// </e>
+PMC_SETUP       EQU     1
+PMC_MOR_Val     EQU     0x00000601
+PMC_PLLR_Val    EQU     0x00191C05
+PMC_MCKR_Val    EQU     0x00000007
+
+
+                PRESERVE8
+                
+
+; Area Definition and Entry Point
+;  Startup Code must be linked first at Address at which it expects to run.
+
+                AREA    RESET, CODE, READONLY
+                ARM
+
+
+; Exception Vectors
+;  Mapped to Address 0.
+;  Absolute addressing mode must be used.
+;  Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors         LDR     PC,Reset_Addr         
+                LDR     PC,Undef_Addr
+                LDR     PC,SWI_Addr
+                LDR     PC,PAbt_Addr
+                LDR     PC,DAbt_Addr
+                NOP                            ; Reserved Vector
+                LDR     PC,IRQ_Addr
+                LDR     PC,FIQ_Addr
+
+Reset_Addr      DCD     Reset_Handler
+Undef_Addr      DCD     Undef_Handler
+SWI_Addr        DCD     SWI_Handler
+PAbt_Addr       DCD     PAbt_Handler
+DAbt_Addr       DCD     DAbt_Handler
+                DCD     0                      ; Reserved Address
+IRQ_Addr        DCD     IRQ_Handler
+FIQ_Addr        DCD     FIQ_Handler
+
+Undef_Handler   B       Undef_Handler
+SWI_Handler     B       SWI_Handler
+PAbt_Handler    B       PAbt_Handler
+DAbt_Handler    B       DAbt_Handler
+FIQ_Handler     B       FIQ_Handler
+
+
+; Reset Handler
+
+                EXPORT  Reset_Handler
+Reset_Handler   
+
+
+; Setup RSTC
+                IF      RSTC_SETUP != 0
+                LDR     R0, =RSTC_BASE
+                LDR     R1, =RSTC_MR_Val
+                STR     R1, [R0, #RSTC_MR]
+                ENDIF
+
+
+; Setup EFC0
+                IF      EFC0_SETUP != 0
+                LDR     R0, =EFC_BASE
+                LDR     R1, =EFC0_FMR_Val
+                STR     R1, [R0, #EFC0_FMR]
+                ENDIF
+
+; Setup EFC1
+                IF      EFC1_SETUP != 0
+                LDR     R0, =EFC_BASE
+                LDR     R1, =EFC1_FMR_Val
+                STR     R1, [R0, #EFC1_FMR]
+                ENDIF
+
+; Setup WDT
+                IF      WDT_SETUP != 0
+                LDR     R0, =WDT_BASE
+                LDR     R1, =WDT_MR_Val
+                STR     R1, [R0, #WDT_MR]
+                ENDIF
+
+
+; Setup PMC
+                IF      PMC_SETUP != 0
+                LDR     R0, =PMC_BASE
+
+;  Setup Main Oscillator
+                LDR     R1, =PMC_MOR_Val
+                STR     R1, [R0, #PMC_MOR]
+
+;  Wait until Main Oscillator is stablilized
+                IF      (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
+MOSCS_Loop      LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MOSCS
+                BEQ     MOSCS_Loop
+                ENDIF
+
+;  Setup the PLL
+                IF      (PMC_PLLR_Val:AND:PMC_MUL) != 0
+                LDR     R1, =PMC_PLLR_Val
+                STR     R1, [R0, #PMC_PLLR]
+
+;  Wait until PLL is stabilized
+PLL_Loop        LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_LOCK
+                BEQ     PLL_Loop
+                ENDIF
+
+;  Select Clock
+                IF      (PMC_MCKR_Val:AND:PMC_CSS) == 1     ; Main Clock Selected
+                LDR     R1, =PMC_MCKR_Val
+                AND     R1, #PMC_CSS
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy1       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy1
+                LDR     R1, =PMC_MCKR_Val
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy2       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy2
+                ELIF    (PMC_MCKR_Val:AND:PMC_CSS) == 3     ; PLL  Clock Selected
+                LDR     R1, =PMC_MCKR_Val
+                AND     R1, #PMC_PRES
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy1       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy1
+                LDR     R1, =PMC_MCKR_Val
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy2       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy2
+                ENDIF   ; Select Clock
+                ENDIF   ; PMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM
+
+                IF      :DEF:RAM_INTVEC
+                ADR     R8, Vectors         ; Source
+                LDR     R9, =RAM_BASE       ; Destination
+                LDMIA   R8!, {R0-R7}        ; Load Vectors 
+                STMIA   R9!, {R0-R7}        ; Store Vectors 
+                LDMIA   R8!, {R0-R7}        ; Load Handler Addresses 
+                STMIA   R9!, {R0-R7}        ; Store Handler Addresses
+                ENDIF
+
+
+; Remap on-chip RAM to address 0
+
+MC_BASE EQU     0xFFFFFF00      ; MC Base Address
+MC_RCR  EQU     0x00            ; MC_RCR Offset
+
+                IF      :DEF:REMAP
+                LDR     R0, =MC_BASE
+                MOV     R1, #1
+                STR     R1, [R0, #MC_RCR]   ; Remap
+                ENDIF
+
+
+; Setup Stack for each mode
+
+                LDR     R0, =Stack_Top
+
+;  Enter Undefined Instruction Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #UND_Stack_Size
+
+;  Enter Abort Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #ABT_Stack_Size
+
+;  Enter FIQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #FIQ_Stack_Size
+
+;  Enter IRQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #IRQ_Stack_Size
+
+;  Enter Supervisor Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #SVC_Stack_Size
+
+;  Enter User Mode and set its Stack Pointer
+                ; MSR     CPSR_c, #Mode_USR
+                IF      :DEF:__MICROLIB
+
+                EXPORT __initial_sp
+
+                ELSE
+
+                MOV     SP, R0
+                SUB     SL, SP, #USR_Stack_Size
+
+                ENDIF
+
+
+; Enter the C code
+
+                IMPORT  __main
+                LDR     R0, =__main
+                BX      R0
+
+				IMPORT rt_interrupt_enter
+				IMPORT rt_interrupt_leave
+				IMPORT rt_thread_switch_interrput_flag
+				IMPORT rt_interrupt_from_thread
+				IMPORT rt_interrupt_to_thread
+				IMPORT rt_hw_trap_irq
+
+IRQ_Handler		PROC
+				EXPORT IRQ_Handler
+				STMFD	sp!, {r0-r12,lr}
+				BL	rt_interrupt_enter
+				BL	rt_hw_trap_irq
+				BL	rt_interrupt_leave
+
+				; if rt_thread_switch_interrput_flag set, jump to
+				; rt_hw_context_switch_interrupt_do and don't return
+				LDR	r0, =rt_thread_switch_interrput_flag
+				LDR	r1, [r0]
+				CMP	r1, #1
+				BEQ	rt_hw_context_switch_interrupt_do
+
+				LDMFD	sp!, {r0-r12,lr}
+				SUBS	pc, lr, #4
+				ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do	PROC
+				EXPORT rt_hw_context_switch_interrupt_do
+				MOV		r1,  #0			; clear flag
+				STR		r1,  [r0]
+
+				LDMFD	sp!, {r0-r12,lr}; reload saved registers
+				STMFD	sp!, {r0-r3}	; save r0-r3
+				MOV		r1,  sp
+				ADD		sp,  sp, #16	; restore sp
+				SUB		r2,  lr, #4		; save old task's pc to r2
+
+				MRS		r3,  spsr		; get cpsr of interrupt thread
+
+				; switch to SVC mode and no interrupt
+                MSR     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+				STMFD	sp!, {r2}		; push old task's pc
+				STMFD	sp!, {r4-r12,lr}; push old task's lr,r12-r4
+				MOV		r4,  r1			; Special optimised code below
+				MOV		r5,  r3
+				LDMFD	r4!, {r0-r3}
+				STMFD	sp!, {r0-r3}	; push old task's r3-r0
+				STMFD	sp!, {r5}		; push old task's cpsr
+				MRS		r4,  spsr
+				STMFD	sp!, {r4}		; push old task's spsr
+
+				LDR		r4,  =rt_interrupt_from_thread
+				LDR		r5,  [r4]
+				STR		sp,  [r5]		; store sp in preempted tasks's TCB
+
+				LDR		r6,  =rt_interrupt_to_thread
+				LDR		r6,  [r6]
+				LDR		sp,  [r6]		; get new task's stack pointer
+			
+				LDMFD	sp!, {r4}		; pop new task's spsr
+				MSR		spsr_cxsf, r4
+				LDMFD	sp!, {r4}		; pop new task's psr
+				MSR		cpsr_cxsf, r4
+
+				LDMFD	sp!, {r0-r12,lr,pc}	; pop new task's r0-r12,lr & pc
+				ENDP
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+; User Initial Stack & Heap
+                AREA    |.text|, CODE, READONLY
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + USR_Stack_Size)
+                LDR     R2, = (Heap_Mem +      Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDIF
+
+                END

+ 40 - 0
libcpu/arm/AT91SAM7S/trap.c

@@ -0,0 +1,40 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-25     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "AT91SAM7S.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+	rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
+
+	hander(AT91C_AIC_ISR);
+
+	/* end of interrupt */
+	AT91C_AIC_EOICR = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+    rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/

+ 342 - 0
libcpu/arm/AT91SAM7X/AT91SAM7X.h

@@ -0,0 +1,342 @@
+/*
+ * File      : at91sam7x.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#ifndef __AT91SAM7S_H__
+#define __AT91SAM7S_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_REG *(volatile unsigned int *)		/* Hardware register definition */
+
+/* ========== Register definition for TC0 peripheral ==========  */
+#define AT91C_TC0_SR		(AT91_REG(0xFFFA0020)) /* TC0 Status Register */
+#define AT91C_TC0_RC		(AT91_REG(0xFFFA001C)) /* TC0 Register C */
+#define AT91C_TC0_RB		(AT91_REG(0xFFFA0018)) /* TC0 Register B */
+#define AT91C_TC0_CCR		(AT91_REG(0xFFFA0000)) /* TC0 Channel Control Register */
+#define AT91C_TC0_CMR		(AT91_REG(0xFFFA0004)) /* TC0 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC0_IER		(AT91_REG(0xFFFA0024)) /* TC0 Interrupt Enable Register */
+#define AT91C_TC0_RA		(AT91_REG(0xFFFA0014)) /* TC0 Register A */
+#define AT91C_TC0_IDR		(AT91_REG(0xFFFA0028)) /* TC0 Interrupt Disable Register */
+#define AT91C_TC0_CV		(AT91_REG(0xFFFA0010)) /* TC0 Counter Value */
+#define AT91C_TC0_IMR		(AT91_REG(0xFFFA002C)) /* TC0 Interrupt Mask Register */
+
+/* ========== Register definition for TC1 peripheral ========== */
+#define AT91C_TC1_RB		(AT91_REG(0xFFFA0058)) /* TC1 Register B */
+#define AT91C_TC1_CCR		(AT91_REG(0xFFFA0040)) /* TC1 Channel Control Register */
+#define AT91C_TC1_IER		(AT91_REG(0xFFFA0064)) /* TC1 Interrupt Enable Register */
+#define AT91C_TC1_IDR		(AT91_REG(0xFFFA0068)) /* TC1 Interrupt Disable Register */
+#define AT91C_TC1_SR		(AT91_REG(0xFFFA0060)) /* TC1 Status Register */
+#define AT91C_TC1_CMR		(AT91_REG(0xFFFA0044)) /* TC1 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC1_RA		(AT91_REG(0xFFFA0054)) /* TC1 Register A */
+#define AT91C_TC1_RC		(AT91_REG(0xFFFA005C)) /* TC1 Register C */
+#define AT91C_TC1_IMR		(AT91_REG(0xFFFA006C)) /* TC1 Interrupt Mask Register */
+#define AT91C_TC1_CV		(AT91_REG(0xFFFA0050)) /* TC1 Counter Value */
+
+/* ========== Register definition for TC2 peripheral ========== */
+#define AT91C_TC2_CMR		(AT91_REG(0xFFFA0084)) /* TC2 Channel Mode Register (Capture Mode / Waveform Mode) */
+#define AT91C_TC2_CCR		(AT91_REG(0xFFFA0080)) /* TC2 Channel Control Register */
+#define AT91C_TC2_CV		(AT91_REG(0xFFFA0090)) /* TC2 Counter Value */
+#define AT91C_TC2_RA		(AT91_REG(0xFFFA0094)) /* TC2 Register A */
+#define AT91C_TC2_RB		(AT91_REG(0xFFFA0098)) /* TC2 Register B */
+#define AT91C_TC2_IDR		(AT91_REG(0xFFFA00A8)) /* TC2 Interrupt Disable Register */
+#define AT91C_TC2_IMR		(AT91_REG(0xFFFA00AC)) /* TC2 Interrupt Mask Register */
+#define AT91C_TC2_RC		(AT91_REG(0xFFFA009C)) /* TC2 Register C */
+#define AT91C_TC2_IER		(AT91_REG(0xFFFA00A4)) /* TC2 Interrupt Enable Register */
+#define AT91C_TC2_SR		(AT91_REG(0xFFFA00A0)) /* TC2 Status Register */
+
+/* ========== Register definition for PITC peripheral ========== */
+#define AT91C_PITC_PIVR		(AT91_REG(0xFFFFFD38)) /* PITC Period Interval Value Register */
+#define AT91C_PITC_PISR		(AT91_REG(0xFFFFFD34)) /* PITC Period Interval Status Register */
+#define AT91C_PITC_PIIR		(AT91_REG(0xFFFFFD3C)) /* PITC Period Interval Image Register */
+#define AT91C_PITC_PIMR		(AT91_REG(0xFFFFFD30)) /* PITC Period Interval Mode Register */
+
+/* ========== Register definition for UDP peripheral ==========  */
+#define AT91C_UDP_NUM		(AT91_REG(0xFFFB0000)) /* UDP Frame Number Register */
+#define AT91C_UDP_STAT		(AT91_REG(0xFFFB0004)) /* UDP Global State Register */
+#define AT91C_UDP_FADDR		(AT91_REG(0xFFFB0008)) /* UDP Function Address Register */
+#define AT91C_UDP_IER		(AT91_REG(0xFFFB0010)) /* UDP Interrupt Enable Register */
+#define AT91C_UDP_IDR		(AT91_REG(0xFFFB0014)) /* UDP Interrupt Disable Register */
+#define AT91C_UDP_IMR		(AT91_REG(0xFFFB0018)) /* UDP Interrupt Mask Register */
+#define AT91C_UDP_ISR		(AT91_REG(0xFFFB001C)) /* UDP Interrupt Status Register */
+#define AT91C_UDP_ICR		(AT91_REG(0xFFFB0020)) /* UDP Interrupt Clear Register */
+#define AT91C_UDP_RSTEP		(AT91_REG(0xFFFB0028)) /* UDP Reset Endpoint Register */
+#define AT91C_UDP_CSR0		(AT91_REG(0xFFFB0030)) /* UDP Endpoint Control and Status Register */
+#define AT91C_UDP_CSR(n)	(*(&AT91C_UDP_CSR0 + n))
+#define AT91C_UDP_FDR0		(AT91_REG(0xFFFB0050)) /* UDP Endpoint FIFO Data Register */
+#define AT91C_UDP_FDR(n)	(*(&AT91C_UDP_FDR0 + n))
+#define AT91C_UDP_TXVC		(AT91_REG(0xFFFB0074)) /* UDP Transceiver Control Register */
+
+/* ========== Register definition for US0 peripheral ========== */
+#define AT91C_US0_CR		(AT91_REG(0xFFFC0000)) /* US0 Control Register */
+#define AT91C_US0_MR		(AT91_REG(0xFFFC0004)) /* US0 Mode Register */
+#define AT91C_US0_IER		(AT91_REG(0xFFFC0008)) /* US0 Interrupt Enable Register */
+#define AT91C_US0_IDR		(AT91_REG(0xFFFC000C)) /* US0 Interrupt Disable Register */
+#define AT91C_US0_IMR		(AT91_REG(0xFFFC0010)) /* US0 Interrupt Mask Register */
+#define AT91C_US0_CSR		(AT91_REG(0xFFFC0014)) /* US0 Channel Status Register */
+#define AT91C_US0_RHR		(AT91_REG(0xFFFC0018)) /* US0 Receiver Holding Register */
+#define AT91C_US0_THR		(AT91_REG(0xFFFC001C)) /* US0 Transmitter Holding Register */
+#define AT91C_US0_BRGR		(AT91_REG(0xFFFC0020)) /* US0 Baud Rate Generator Register */
+#define AT91C_US0_RTOR		(AT91_REG(0xFFFC0024)) /* US0 Receiver Time-out Register */
+#define AT91C_US0_TTGR		(AT91_REG(0xFFFC0028)) /* US0 Transmitter Time-guard Register */
+#define AT91C_US0_NER		(AT91_REG(0xFFFC0044)) /* US0 Nb Errors Register */
+#define AT91C_US0_FIDI		(AT91_REG(0xFFFC0040)) /* US0 FI_DI_Ratio Register */
+#define AT91C_US0_IF		(AT91_REG(0xFFFC004C)) /* US0 IRDA_FILTER Register */
+
+/* ========== Register definition for AIC peripheral ==========  */
+#define AT91C_AIC_SMR0		(AT91_REG(0xFFFFF000)) /* AIC Source Mode Register */
+#define AT91C_AIC_SMR(n)	(*(&AT91C_AIC_SMR0 + n))
+#define AT91C_AIC_SVR0		(AT91_REG(0xFFFFF080)) /* AIC Source Vector Register */
+#define AT91C_AIC_SVR(n)	(*(&AT91C_AIC_SVR0 + n))
+#define AT91C_AIC_IVR		(AT91_REG(0xFFFFF100)) /* AIC Interrupt Vector Register */
+#define AT91C_AIC_FVR		(AT91_REG(0xFFFFF104)) /* AIC FIQ Vector Register */
+#define AT91C_AIC_ISR		(AT91_REG(0xFFFFF108)) /* AIC Interrupt Status Register */
+#define AT91C_AIC_IPR		(AT91_REG(0xFFFFF10C)) /* AIC Interrupt Pending Register */
+#define AT91C_AIC_IMR		(AT91_REG(0xFFFFF110)) /* AIC Interrupt Mask Register */
+#define AT91C_AIC_CISR		(AT91_REG(0xFFFFF114)) /* AIC Core Interrupt Status Register */
+#define AT91C_AIC_IECR		(AT91_REG(0xFFFFF120)) /* AIC Interrupt Enable Command Register */
+#define AT91C_AIC_IDCR		(AT91_REG(0xFFFFF124)) /* AIC Interrupt Disable Command Register */
+#define AT91C_AIC_ICCR		(AT91_REG(0xFFFFF128)) /* AIC Interrupt Clear Command Register */
+#define AT91C_AIC_ISCR		(AT91_REG(0xFFFFF12C)) /* AIC Interrupt Set Command Register */
+#define AT91C_AIC_EOICR		(AT91_REG(0xFFFFF130)) /* AIC End of Interrupt Command Register */
+#define AT91C_AIC_SPU		(AT91_REG(0xFFFFF134)) /* AIC Spurious Vector Register */
+#define AT91C_AIC_DCR		(AT91_REG(0xFFFFF138)) /* AIC Debug Control Register (Protect) */
+#define AT91C_AIC_FFER		(AT91_REG(0xFFFFF140)) /* AIC Fast Forcing Enable Register */
+#define AT91C_AIC_FFDR		(AT91_REG(0xFFFFF144)) /* AIC Fast Forcing Disable Register */
+#define AT91C_AIC_FFSR		(AT91_REG(0xFFFFF148)) /* AIC Fast Forcing Status Register */
+
+
+/* ========== Register definition for DBGU peripheral ==========  */
+#define AT91C_DBGU_EXID		(AT91_REG(0xFFFFF244)) /* DBGU Chip ID Extension Register */
+#define AT91C_DBGU_BRGR		(AT91_REG(0xFFFFF220)) /* DBGU Baud Rate Generator Register */
+#define AT91C_DBGU_IDR		(AT91_REG(0xFFFFF20C)) /* DBGU Interrupt Disable Register */
+#define AT91C_DBGU_CSR		(AT91_REG(0xFFFFF214)) /* DBGU Channel Status Register */
+#define AT91C_DBGU_CIDR		(AT91_REG(0xFFFFF240)) /* DBGU Chip ID Register */
+#define AT91C_DBGU_MR		(AT91_REG(0xFFFFF204)) /* DBGU Mode Register */
+#define AT91C_DBGU_IMR		(AT91_REG(0xFFFFF210)) /* DBGU Interrupt Mask Register */
+#define AT91C_DBGU_CR		(AT91_REG(0xFFFFF200)) /* DBGU Control Register */
+#define AT91C_DBGU_FNTR		(AT91_REG(0xFFFFF248)) /* DBGU Force NTRST Register */
+#define AT91C_DBGU_THR		(AT91_REG(0xFFFFF21C)) /* DBGU Transmitter Holding Register */
+#define AT91C_DBGU_RHR		(AT91_REG(0xFFFFF218)) /* DBGU Receiver Holding Register */
+#define AT91C_DBGU_IER		(AT91_REG(0xFFFFF208)) /* DBGU Interrupt Enable Register */
+
+/* ========== Register definition for PIO peripheral ========== */
+#define AT91C_PIO_ODR		(AT91_REG(0xFFFFF414)) /* PIOA Output Disable Registerr */
+#define AT91C_PIO_SODR		(AT91_REG(0xFFFFF430)) /* PIOA Set Output Data Register */
+#define AT91C_PIO_ISR		(AT91_REG(0xFFFFF44C)) /* PIOA Interrupt Status Register */
+#define AT91C_PIO_ABSR		(AT91_REG(0xFFFFF478)) /* PIOA AB Select Status Register */
+#define AT91C_PIO_IER		(AT91_REG(0xFFFFF440)) /* PIOA Interrupt Enable Register */
+#define AT91C_PIO_PPUDR		(AT91_REG(0xFFFFF460)) /* PIOA Pull-up Disable Register */
+#define AT91C_PIO_IMR		(AT91_REG(0xFFFFF448)) /* PIOA Interrupt Mask Register */
+#define AT91C_PIO_PER		(AT91_REG(0xFFFFF400)) /* PIOA PIO Enable Register */
+#define AT91C_PIO_IFDR		(AT91_REG(0xFFFFF424)) /* PIOA Input Filter Disable Register */
+#define AT91C_PIO_OWDR		(AT91_REG(0xFFFFF4A4)) /* PIOA Output Write Disable Register */
+#define AT91C_PIO_MDSR		(AT91_REG(0xFFFFF458)) /* PIOA Multi-driver Status Register */
+#define AT91C_PIO_IDR		(AT91_REG(0xFFFFF444)) /* PIOA Interrupt Disable Register */
+#define AT91C_PIO_ODSR		(AT91_REG(0xFFFFF438)) /* PIOA Output Data Status Register */
+#define AT91C_PIO_PPUSR		(AT91_REG(0xFFFFF468)) /* PIOA Pull-up Status Register */
+#define AT91C_PIO_OWSR		(AT91_REG(0xFFFFF4A8)) /* PIOA Output Write Status Register */
+#define AT91C_PIO_BSR		(AT91_REG(0xFFFFF474)) /* PIOA Select B Register */
+#define AT91C_PIO_OWER		(AT91_REG(0xFFFFF4A0)) /* PIOA Output Write Enable Register */
+#define AT91C_PIO_IFER		(AT91_REG(0xFFFFF420)) /* PIOA Input Filter Enable Register */
+#define AT91C_PIO_PDSR		(AT91_REG(0xFFFFF43C)) /* PIOA Pin Data Status Register */
+#define AT91C_PIO_PPUER		(AT91_REG(0xFFFFF464)) /* PIOA Pull-up Enable Register */
+#define AT91C_PIO_OSR		(AT91_REG(0xFFFFF418)) /* PIOA Output Status Register */
+#define AT91C_PIO_ASR		(AT91_REG(0xFFFFF470)) /* PIOA Select A Register */
+#define AT91C_PIO_MDDR		(AT91_REG(0xFFFFF454)) /* PIOA Multi-driver Disable Register */
+#define AT91C_PIO_CODR		(AT91_REG(0xFFFFF434)) /* PIOA Clear Output Data Register */
+#define AT91C_PIO_MDER		(AT91_REG(0xFFFFF450)) /* PIOA Multi-driver Enable Register */
+#define AT91C_PIO_PDR		(AT91_REG(0xFFFFF404)) /* PIOA PIO Disable Register */
+#define AT91C_PIO_IFSR		(AT91_REG(0xFFFFF428)) /* PIOA Input Filter Status Register */
+#define AT91C_PIO_OER		(AT91_REG(0xFFFFF410)) /* PIOA Output Enable Register */
+#define AT91C_PIO_PSR		(AT91_REG(0xFFFFF408)) /* PIOA PIO Status Register */
+
+// ========== Register definition for PIOA peripheral ==========
+#define AT91C_PIOA_IMR  	(AT91_REG(0xFFFFF448)) // (PIOA) Interrupt Mask Register
+#define AT91C_PIOA_IER  	(AT91_REG(0xFFFFF440)) // (PIOA) Interrupt Enable Register
+#define AT91C_PIOA_OWDR 	(AT91_REG(0xFFFFF4A4)) // (PIOA) Output Write Disable Register
+#define AT91C_PIOA_ISR  	(AT91_REG(0xFFFFF44C)) // (PIOA) Interrupt Status Register
+#define AT91C_PIOA_PPUDR 	(AT91_REG(0xFFFFF460)) // (PIOA) Pull-up Disable Register
+#define AT91C_PIOA_MDSR 	(AT91_REG(0xFFFFF458)) // (PIOA) Multi-driver Status Register
+#define AT91C_PIOA_MDER 	(AT91_REG(0xFFFFF450)) // (PIOA) Multi-driver Enable Register
+#define AT91C_PIOA_PER  	(AT91_REG(0xFFFFF400)) // (PIOA) PIO Enable Register
+#define AT91C_PIOA_PSR  	(AT91_REG(0xFFFFF408)) // (PIOA) PIO Status Register
+#define AT91C_PIOA_OER  	(AT91_REG(0xFFFFF410)) // (PIOA) Output Enable Register
+#define AT91C_PIOA_BSR  	(AT91_REG(0xFFFFF474)) // (PIOA) Select B Register
+#define AT91C_PIOA_PPUER 	(AT91_REG(0xFFFFF464)) // (PIOA) Pull-up Enable Register
+#define AT91C_PIOA_MDDR 	(AT91_REG(0xFFFFF454)) // (PIOA) Multi-driver Disable Register
+#define AT91C_PIOA_PDR  	(AT91_REG(0xFFFFF404)) // (PIOA) PIO Disable Register
+#define AT91C_PIOA_ODR  	(AT91_REG(0xFFFFF414)) // (PIOA) Output Disable Registerr
+#define AT91C_PIOA_IFDR 	(AT91_REG(0xFFFFF424)) // (PIOA) Input Filter Disable Register
+#define AT91C_PIOA_ABSR 	(AT91_REG(0xFFFFF478)) // (PIOA) AB Select Status Register
+#define AT91C_PIOA_ASR  	(AT91_REG(0xFFFFF470)) // (PIOA) Select A Register
+#define AT91C_PIOA_PPUSR 	(AT91_REG(0xFFFFF468)) // (PIOA) Pull-up Status Register
+#define AT91C_PIOA_ODSR 	(AT91_REG(0xFFFFF438)) // (PIOA) Output Data Status Register
+#define AT91C_PIOA_SODR 	(AT91_REG(0xFFFFF430)) // (PIOA) Set Output Data Register
+#define AT91C_PIOA_IFSR 	(AT91_REG(0xFFFFF428)) // (PIOA) Input Filter Status Register
+#define AT91C_PIOA_IFER 	(AT91_REG(0xFFFFF420)) // (PIOA) Input Filter Enable Register
+#define AT91C_PIOA_OSR  	(AT91_REG(0xFFFFF418)) // (PIOA) Output Status Register
+#define AT91C_PIOA_IDR  	(AT91_REG(0xFFFFF444)) // (PIOA) Interrupt Disable Register
+#define AT91C_PIOA_PDSR 	(AT91_REG(0xFFFFF43C)) // (PIOA) Pin Data Status Register
+#define AT91C_PIOA_CODR 	(AT91_REG(0xFFFFF434)) // (PIOA) Clear Output Data Register
+#define AT91C_PIOA_OWSR 	(AT91_REG(0xFFFFF4A8)) // (PIOA) Output Write Status Register
+#define AT91C_PIOA_OWER 	(AT91_REG(0xFFFFF4A0)) // (PIOA) Output Write Enable Register
+// ========== Register definition for PIOB peripheral ==========
+#define AT91C_PIOB_OWSR 	(AT91_REG(0xFFFFF6A8)) // (PIOB) Output Write Status Register
+#define AT91C_PIOB_PPUSR 	(AT91_REG(0xFFFFF668)) // (PIOB) Pull-up Status Register
+#define AT91C_PIOB_PPUDR 	(AT91_REG(0xFFFFF660)) // (PIOB) Pull-up Disable Register
+#define AT91C_PIOB_MDSR 	(AT91_REG(0xFFFFF658)) // (PIOB) Multi-driver Status Register
+#define AT91C_PIOB_MDER 	(AT91_REG(0xFFFFF650)) // (PIOB) Multi-driver Enable Register
+#define AT91C_PIOB_IMR  	(AT91_REG(0xFFFFF648)) // (PIOB) Interrupt Mask Register
+#define AT91C_PIOB_OSR  	(AT91_REG(0xFFFFF618)) // (PIOB) Output Status Register
+#define AT91C_PIOB_OER  	(AT91_REG(0xFFFFF610)) // (PIOB) Output Enable Register
+#define AT91C_PIOB_PSR  	(AT91_REG(0xFFFFF608)) // (PIOB) PIO Status Register
+#define AT91C_PIOB_PER  	(AT91_REG(0xFFFFF600)) // (PIOB) PIO Enable Register
+#define AT91C_PIOB_BSR  	(AT91_REG(0xFFFFF674)) // (PIOB) Select B Register
+#define AT91C_PIOB_PPUER 	(AT91_REG(0xFFFFF664)) // (PIOB) Pull-up Enable Register
+#define AT91C_PIOB_IFDR 	(AT91_REG(0xFFFFF624)) // (PIOB) Input Filter Disable Register
+#define AT91C_PIOB_ODR  	(AT91_REG(0xFFFFF614)) // (PIOB) Output Disable Registerr
+#define AT91C_PIOB_ABSR 	(AT91_REG(0xFFFFF678)) // (PIOB) AB Select Status Register
+#define AT91C_PIOB_ASR  	(AT91_REG(0xFFFFF670)) // (PIOB) Select A Register
+#define AT91C_PIOB_IFER 	(AT91_REG(0xFFFFF620)) // (PIOB) Input Filter Enable Register
+#define AT91C_PIOB_IFSR 	(AT91_REG(0xFFFFF628)) // (PIOB) Input Filter Status Register
+#define AT91C_PIOB_SODR 	(AT91_REG(0xFFFFF630)) // (PIOB) Set Output Data Register
+#define AT91C_PIOB_ODSR 	(AT91_REG(0xFFFFF638)) // (PIOB) Output Data Status Register
+#define AT91C_PIOB_CODR 	(AT91_REG(0xFFFFF634)) // (PIOB) Clear Output Data Register
+#define AT91C_PIOB_PDSR 	(AT91_REG(0xFFFFF63C)) // (PIOB) Pin Data Status Register
+#define AT91C_PIOB_OWER 	(AT91_REG(0xFFFFF6A0)) // (PIOB) Output Write Enable Register
+#define AT91C_PIOB_IER  	(AT91_REG(0xFFFFF640)) // (PIOB) Interrupt Enable Register
+#define AT91C_PIOB_OWDR 	(AT91_REG(0xFFFFF6A4)) // (PIOB) Output Write Disable Register
+#define AT91C_PIOB_MDDR 	(AT91_REG(0xFFFFF654)) // (PIOB) Multi-driver Disable Register
+#define AT91C_PIOB_ISR  	(AT91_REG(0xFFFFF64C)) // (PIOB) Interrupt Status Register
+#define AT91C_PIOB_IDR  	(AT91_REG(0xFFFFF644)) // (PIOB) Interrupt Disable Register
+#define AT91C_PIOB_PDR  	(AT91_REG(0xFFFFF604)) // (PIOB) PIO Disable Register
+
+/* ========== Register definition for PMC peripheral ========== */
+#define AT91C_PMC_SCER		(AT91_REG(0xFFFFFC00)) /* PMC System Clock Enable Register */
+#define AT91C_PMC_SCDR		(AT91_REG(0xFFFFFC04)) /* PMC System Clock Disable Register */
+#define AT91C_PMC_SCSR		(AT91_REG(0xFFFFFC08)) /* PMC System Clock Status Register */
+#define AT91C_PMC_PCER		(AT91_REG(0xFFFFFC10)) /* PMC Peripheral Clock Enable Register */
+#define AT91C_PMC_PCDR		(AT91_REG(0xFFFFFC14)) /* PMC Peripheral Clock Disable Register */
+#define AT91C_PMC_PCSR		(AT91_REG(0xFFFFFC18)) /* PMC Peripheral Clock Status Register */
+#define AT91C_PMC_MOR		(AT91_REG(0xFFFFFC20)) /* PMC Main Oscillator Register */
+#define AT91C_PMC_MCFR		(AT91_REG(0xFFFFFC24)) /* PMC Main Clock  Frequency Register */
+#define AT91C_PMC_PLLR		(AT91_REG(0xFFFFFC2C)) /* PMC PLL Register */
+#define AT91C_PMC_MCKR		(AT91_REG(0xFFFFFC30)) /* PMC Master Clock Register */
+#define AT91C_PMC_PCKR		(AT91_REG(0xFFFFFC40)) /* PMC Programmable Clock Register */
+#define AT91C_PMC_IER		(AT91_REG(0xFFFFFC60)) /* PMC Interrupt Enable Register */
+#define AT91C_PMC_IDR		(AT91_REG(0xFFFFFC64)) /* PMC Interrupt Disable Register */
+#define AT91C_PMC_SR		(AT91_REG(0xFFFFFC68)) /* PMC Status Register */
+#define AT91C_PMC_IMR		(AT91_REG(0xFFFFFC6C)) /* PMC Interrupt Mask Register */
+
+// ========== Register definition for PDC_SPI1 peripheral ========== 
+#define AT91C_SPI1_RNPR      (AT91_REG(0xFFFE4110)) // (PDC_SPI1) Receive Next Pointer Register
+#define AT91C_SPI1_TPR       (AT91_REG(0xFFFE4108)) // (PDC_SPI1) Transmit Pointer Register
+#define AT91C_SPI1_RPR       (AT91_REG(0xFFFE4100)) // (PDC_SPI1) Receive Pointer Register
+#define AT91C_SPI1_PTSR      (AT91_REG(0xFFFE4124)) // (PDC_SPI1) PDC Transfer Status Register
+#define AT91C_SPI1_RCR       (AT91_REG(0xFFFE4104)) // (PDC_SPI1) Receive Counter Register
+#define AT91C_SPI1_TCR       (AT91_REG(0xFFFE410C)) // (PDC_SPI1) Transmit Counter Register
+#define AT91C_SPI1_RNCR      (AT91_REG(0xFFFE4114)) // (PDC_SPI1) Receive Next Counter Register
+#define AT91C_SPI1_TNCR      (AT91_REG(0xFFFE411C)) // (PDC_SPI1) Transmit Next Counter Register
+#define AT91C_SPI1_TNPR      (AT91_REG(0xFFFE4118)) // (PDC_SPI1) Transmit Next Pointer Register
+#define AT91C_SPI1_PTCR      (AT91_REG(0xFFFE4120)) // (PDC_SPI1) PDC Transfer Control Register
+// ========== Register definition for SPI1 peripheral ========== 
+#define AT91C_SPI1_CSR       (AT91_REG(0xFFFE4030)) // (SPI1) Chip Select Register
+#define AT91C_SPI1_IDR       (AT91_REG(0xFFFE4018)) // (SPI1) Interrupt Disable Register
+#define AT91C_SPI1_SR        (AT91_REG(0xFFFE4010)) // (SPI1) Status Register
+#define AT91C_SPI1_RDR       (AT91_REG(0xFFFE4008)) // (SPI1) Receive Data Register
+#define AT91C_SPI1_CR        (AT91_REG(0xFFFE4000)) // (SPI1) Control Register
+#define AT91C_SPI1_IMR       (AT91_REG(0xFFFE401C)) // (SPI1) Interrupt Mask Register
+#define AT91C_SPI1_IER       (AT91_REG(0xFFFE4014)) // (SPI1) Interrupt Enable Register
+#define AT91C_SPI1_TDR       (AT91_REG(0xFFFE400C)) // (SPI1) Transmit Data Register
+#define AT91C_SPI1_MR        (AT91_REG(0xFFFE4004)) // (SPI1) Mode Register
+// ========== Register definition for PDC_SPI0 peripheral ========== 
+#define AT91C_SPI0_PTCR      (AT91_REG(0xFFFE0120)) // (PDC_SPI0) PDC Transfer Control Register
+#define AT91C_SPI0_TNPR      (AT91_REG(0xFFFE0118)) // (PDC_SPI0) Transmit Next Pointer Register
+#define AT91C_SPI0_RNPR      (AT91_REG(0xFFFE0110)) // (PDC_SPI0) Receive Next Pointer Register
+#define AT91C_SPI0_TPR       (AT91_REG(0xFFFE0108)) // (PDC_SPI0) Transmit Pointer Register
+#define AT91C_SPI0_RPR       (AT91_REG(0xFFFE0100)) // (PDC_SPI0) Receive Pointer Register
+#define AT91C_SPI0_PTSR      (AT91_REG(0xFFFE0124)) // (PDC_SPI0) PDC Transfer Status Register
+#define AT91C_SPI0_TNCR      (AT91_REG(0xFFFE011C)) // (PDC_SPI0) Transmit Next Counter Register
+#define AT91C_SPI0_RNCR      (AT91_REG(0xFFFE0114)) // (PDC_SPI0) Receive Next Counter Register
+#define AT91C_SPI0_TCR       (AT91_REG(0xFFFE010C)) // (PDC_SPI0) Transmit Counter Register
+#define AT91C_SPI0_RCR       (AT91_REG(0xFFFE0104)) // (PDC_SPI0) Receive Counter Register
+// ========== Register definition for SPI0 peripheral ========== 
+#define AT91C_SPI0_CSR       (AT91_REG(0xFFFE0030)) // (SPI0) Chip Select Register
+#define AT91C_SPI0_IDR       (AT91_REG(0xFFFE0018)) // (SPI0) Interrupt Disable Register
+#define AT91C_SPI0_SR        (AT91_REG(0xFFFE0010)) // (SPI0) Status Register
+#define AT91C_SPI0_RDR       (AT91_REG(0xFFFE0008)) // (SPI0) Receive Data Register
+#define AT91C_SPI0_CR        (AT91_REG(0xFFFE0000)) // (SPI0) Control Register
+#define AT91C_SPI0_IMR       (AT91_REG(0xFFFE001C)) // (SPI0) Interrupt Mask Register
+#define AT91C_SPI0_IER       (AT91_REG(0xFFFE0014)) // (SPI0) Interrupt Enable Register
+#define AT91C_SPI0_TDR       (AT91_REG(0xFFFE000C)) // (SPI0) Transmit Data Register
+#define AT91C_SPI0_MR        (AT91_REG(0xFFFE0004)) // (SPI0) Mode Register
+
+/******************************************************************************/
+/*               PERIPHERAL ID DEFINITIONS FOR AT91SAM7X256                   */
+/******************************************************************************/
+#define AT91C_ID_FIQ              ( 0) /* Advanced Interrupt Controller (FIQ) */
+#define AT91C_ID_SYS              ( 1) /* System Peripheral */
+#define AT91C_ID_PIOA             ( 2) /* Parallel IO Controller A */
+#define AT91C_ID_PIOB             ( 3) /* Parallel IO Controller B */
+#define AT91C_ID_SPI0             ( 4) /* Serial Peripheral Interface 0 */
+#define AT91C_ID_SPI1             ( 5) /* Serial Peripheral Interface 1 */
+#define AT91C_ID_US0              ( 6) /* USART 0 */
+#define AT91C_ID_US1              ( 7) /* USART 1 */
+#define AT91C_ID_SSC              ( 8) /* Serial Synchronous Controller */
+#define AT91C_ID_TWI              ( 9) /* Two-Wire Interface */
+#define AT91C_ID_PWMC             (10) /* PWM Controller */
+#define AT91C_ID_UDP              (11) /* USB Device Port */
+#define AT91C_ID_TC0              (12) /* Timer Counter 0 */
+#define AT91C_ID_TC1              (13) /* Timer Counter 1 */
+#define AT91C_ID_TC2              (14) /* Timer Counter 2 */
+#define AT91C_ID_CAN              (15) /* Control Area Network Controller */
+#define AT91C_ID_EMAC             (16) /* Ethernet MAC */
+#define AT91C_ID_ADC              (17) /* Analog-to-Digital Converter */
+#define AT91C_ID_AES              (18) /* Advanced Encryption Standard 128-bit */
+#define AT91C_ID_TDES             (19) /* Triple Data Encryption Standard */
+#define AT91C_ID_20_Reserved      (20) /* Reserved */
+#define AT91C_ID_21_Reserved      (21) /* Reserved */
+#define AT91C_ID_22_Reserved      (22) /* Reserved */
+#define AT91C_ID_23_Reserved      (23) /* Reserved */
+#define AT91C_ID_24_Reserved      (24) /* Reserved */
+#define AT91C_ID_25_Reserved      (25) /* Reserved */
+#define AT91C_ID_26_Reserved      (26) /* Reserved */
+#define AT91C_ID_27_Reserved      (27) /* Reserved */
+#define AT91C_ID_28_Reserved      (28) /* Reserved */
+#define AT91C_ID_29_Reserved      (29) /* Reserved */
+#define AT91C_ID_IRQ0             (30) /* Advanced Interrupt Controller (IRQ0) */
+#define AT91C_ID_IRQ1             (31) /* Advanced Interrupt Controller (IRQ1) */
+#define AT91C_ALL_INT             (0xC00FFFFF) /* ALL VALID INTERRUPTS */
+
+#define MCK	48054857
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE			0x10
+#define FIQMODE				0x11
+#define IRQMODE				0x12
+#define SVCMODE				0x13
+#define ABORTMODE			0x17
+#define UNDEFMODE			0x1b
+#define MODEMASK			0x1f
+#define NOINT				0xc0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 99 - 0
libcpu/arm/AT91SAM7X/context_gcc.S

@@ -0,0 +1,99 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ */
+
+/*!
+ * \addtogroup xgs3c4510
+ */
+/*@{*/
+
+#define NOINT			0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	ldr	sp, [r1]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr	sp, [r0]		@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr r2, =rt_thread_switch_interrput_flag
+	ldr r3, [r2]
+	cmp r3, #1
+	beq _reswitch
+	mov r3, #1				@ set rt_thread_switch_interrput_flag to 1
+	str r3, [r2]
+	ldr r2, =rt_interrupt_from_thread	@ set rt_interrupt_from_thread
+	str r0, [r2]
+_reswitch:
+	ldr r2, =rt_interrupt_to_thread		@ set rt_interrupt_to_thread
+	str r1, [r2]
+	mov pc, lr

+ 107 - 0
libcpu/arm/AT91SAM7X/context_rvds.S

@@ -0,0 +1,107 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-20     Bernard      first version
+; */
+
+NOINT	EQU		0xc0	; disable interrupt in psr
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	ARM
+	REQUIRE8
+	PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable	PROC
+	EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable	PROC
+	EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch	PROC
+	EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
+	STMFD	sp!, {r0-r12, lr}	; push lr & register file
+
+	MRS		r4, cpsr
+	STMFD	sp!, {r4}			; push cpsr
+	MRS		r4, spsr
+	STMFD	sp!, {r4}			; push spsr
+
+	STR	sp, [r0]				; store sp in preempted tasks TCB
+	LDR	sp, [r1]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to	PROC
+	EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt	PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]
+	CMP r3, #1
+	BEQ _reswitch
+	MOV r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR r3, [r2]
+	LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR r0, [r2]
+_reswitch
+	LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR r1, [r2]
+	BX	lr
+	ENDP
+
+	END

+ 42 - 0
libcpu/arm/AT91SAM7X/cpu.c

@@ -0,0 +1,42 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7X
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/

+ 91 - 0
libcpu/arm/AT91SAM7X/interrupt.c

@@ -0,0 +1,91 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+#define MAX_HANDLERS	32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	rt_base_t index;
+
+	for (index = 0; index < MAX_HANDLERS; index ++)
+	{
+		AT91C_AIC_SVR(index) = (rt_uint32_t)rt_hw_interrupt_handler;
+	}
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	/* disable interrupt */
+	AT91C_AIC_IDCR = 1 << vector;
+
+	/* clear interrupt */
+	AT91C_AIC_ICCR = 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	AT91C_AIC_IECR = 1 << vector;
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	if(vector >= 0 && vector < MAX_HANDLERS)
+	{
+		if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)AT91C_AIC_SVR(vector);
+		if (new_handler != RT_NULL) AT91C_AIC_SVR(vector) = (rt_uint32_t)new_handler;
+	}
+}
+
+/*@}*/

+ 156 - 0
libcpu/arm/AT91SAM7X/mii.h

@@ -0,0 +1,156 @@
+/*
+    ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+    This file is part of ChibiOS/RT.
+
+    ChibiOS/RT is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    ChibiOS/RT is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Parts of this file are borrowed by the Linux include file linux/mii.h:
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _MII_H_
+#define _MII_H_
+
+/* Generic MII registers. */
+#define MII_BMCR            0x00        /* Basic mode control register */
+#define MII_BMSR            0x01        /* Basic mode status register  */
+#define MII_PHYSID1         0x02        /* PHYS ID 1                   */
+#define MII_PHYSID2         0x03        /* PHYS ID 2                   */
+#define MII_ADVERTISE       0x04        /* Advertisement control reg   */
+#define MII_LPA             0x05        /* Link partner ability reg    */
+#define MII_EXPANSION       0x06        /* Expansion register          */
+#define MII_CTRL1000        0x09        /* 1000BASE-T control          */
+#define MII_STAT1000        0x0a        /* 1000BASE-T status           */
+#define MII_ESTATUS         0x0f        /* Extended Status */
+#define MII_DCOUNTER        0x12        /* Disconnect counter          */
+#define MII_FCSCOUNTER      0x13        /* False carrier counter       */
+#define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15        /* Receive error counter       */
+#define MII_SREVISION       0x16        /* Silicon revision            */
+#define MII_RESV1           0x17        /* Reserved...                 */
+#define MII_LBRERROR        0x18        /* Lpback, rx, bypass error    */
+#define MII_PHYADDR         0x19        /* PHY address                 */
+#define MII_RESV2           0x1a        /* Reserved...                 */
+#define MII_TPISTATUS       0x1b        /* TPI status for 10mbps       */
+#define MII_NCONFIG         0x1c        /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV               0x003f  /* Unused...                   */
+#define BMCR_SPEED1000          0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST               0x0080  /* Collision test              */
+#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */
+#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */
+#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */
+#define BMCR_RESET              0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP              0x0001  /* Ext-reg capability          */
+#define BMSR_JCD                0x0002  /* Jabber detected             */
+#define BMSR_LSTATUS            0x0004  /* Link status                 */
+#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT             0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV               0x00c0  /* Unused...                   */
+#define BMSR_ESTATEN            0x0100  /* Extended Status in R15 */
+#define BMSR_100HALF2           0x0200  /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2           0x0400  /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT          0x001f  /* Selector bits               */
+#define ADVERTISE_CSMA          0x0001  /* Only selector supported     */
+#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL     0x0020  /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF     0x0040  /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause    */
+#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
+#define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause               */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
+#define ADVERTISE_RESV          0x1000  /* Unused...                   */
+#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */
+#define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */
+#define ADVERTISE_NPAGE         0x8000  /* Next page bit               */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+                        ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+                       ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT                0x001f  /* Same as advertise selector  */
+#define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_1000XFULL           0x0020  /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_1000XHALF           0x0040  /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_1000XPAUSE          0x0080  /* Can do 1000BASE-X pause     */
+#define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_1000XPAUSE_ASYM     0x0100  /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
+#define LPA_PAUSE_CAP           0x0400  /* Can pause                   */
+#define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically     */
+#define LPA_RESV                0x1000  /* Unused...                   */
+#define LPA_RFAULT              0x2000  /* Link partner faulted        */
+#define LPA_LPACK               0x4000  /* Link partner acked us       */
+#define LPA_NPAGE               0x8000  /* Next page bit               */
+
+#define LPA_DUPLEX              (LPA_10FULL | LPA_100FULL)
+#define LPA_100                 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY          0x0001  /* Can do N-way auto-nego      */
+#define EXPANSION_LCWP          0x0002  /* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words    */
+#define EXPANSION_NPCAPABLE     0x0008  /* Link partner supports npage */
+#define EXPANSION_MFAULTS       0x0010  /* Multiple faults detected    */
+#define EXPANSION_RESV          0xffe0  /* Unused...                   */
+
+#define ESTATUS_1000_TFULL      0x2000  /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF      0x1000  /* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1          0x00ff  /* Unused...                   */
+#define NWAYTEST_LOOPBACK       0x0100  /* Enable loopback for N-way   */
+#define NWAYTEST_RESV2          0xfe00  /* Unused...                   */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK       0x2000  /* Link partner local receiver status */
+#define LPA_1000REMRXOK         0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
+
+#define MII_DM9161_ID     0x0181b8a0
+#define MII_AM79C875_ID   0x00225540
+#define MII_MICREL_ID     0x00221610
+
+#endif /* _MII_H_ */

+ 554 - 0
libcpu/arm/AT91SAM7X/sam7x_emac.c

@@ -0,0 +1,554 @@
+#include <rthw.h>
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+
+#include "sam7x_emac.h"
+#include "AT91SAM7X256.h"
+#include "lwipopts.h"
+
+#define MAX_ADDR_LEN 6
+#define EMAC_PIO_CFG	(AT91C_PB0_ETXCK_EREFCK | \
+		AT91C_PB1_ETXEN        | \
+		AT91C_PB2_ETX0         | \
+		AT91C_PB3_ETX1         | \
+		AT91C_PB4_ECRS         | \
+		AT91C_PB5_ERX0         | \
+		AT91C_PB6_ERX1         | \
+		AT91C_PB7_ERXER        | \
+		AT91C_PB8_EMDC         | \
+		AT91C_PB9_EMDIO        | \
+		AT91C_PB10_ETX2        | \
+		AT91C_PB11_ETX3        | \
+		AT91C_PB10_ETX2		   | \
+		AT91C_PB13_ERX2        | \
+		AT91C_PB14_ERX3        | \
+		AT91C_PB15_ERXDV_ECRSDV| \
+		AT91C_PB16_ECOL        | \
+		AT91C_PB17_ERXCK)
+
+#define RB_BUFFER_SIZE		8			/* max number of receive buffers */
+#define ETH_RX_BUF_SIZE		128
+
+#define TB_BUFFER_SIZE		4
+#define ETH_TX_BUF_SIZE		(PBUF_POOL_BUFSIZE)
+
+struct rbf_t
+{
+	rt_uint32_t addr;
+	rt_uint32_t status;
+};
+
+static rt_uint32_t 	current_rb_index;						/* current receive buffer index */
+static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
+static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
+static rt_uint8_t 	rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
+static rt_uint8_t 	tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
+static struct rt_semaphore tx_sem;
+
+struct net_device
+{
+	/* inherit from ethernet device */
+	struct eth_device parent;
+
+	/* interface address info. */
+	rt_uint8_t  dev_addr[MAX_ADDR_LEN];			/* hw address	*/
+};
+static struct net_device  sam7x_dev_entry;
+static struct net_device *sam7x_dev =&sam7x_dev_entry;
+AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
+
+rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
+{
+	AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
+								 (AT91C_PHY_ADDR << 23) | (addr << 18))  | value;
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
+}
+
+rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
+{
+	AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
+								(AT91C_PHY_ADDR << 23) | (addr << 18);
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
+
+	return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
+}
+
+rt_inline void sam7xether_reset_tx_desc(void)
+{
+	static rt_uint32_t index = 0;
+
+	if(tb_descriptors[index].status & TxDESC_STATUS_USED)
+	{
+		while(!tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF)
+		{
+			index ++;
+			if(index >= TB_BUFFER_SIZE)index = 0;
+
+			tb_descriptors[index].status |= TxDESC_STATUS_USED;
+		}
+
+		index ++;
+		if(index >= TB_BUFFER_SIZE)index = 0;
+	}
+}
+
+/* interrupt service routing */
+static void sam7xether_isr(int irq)
+{
+	/* Variable definitions can be made now. */
+	volatile rt_uint32_t isr, rsr;
+	
+	/* get status */
+	isr = AT91C_BASE_EMAC->EMAC_ISR;
+	rsr = AT91C_BASE_EMAC->EMAC_RSR;
+
+	if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
+	{
+		rt_err_t result;
+
+		/* a frame has been received */
+		result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
+		RT_ASSERT(result == RT_EOK);
+
+		AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
+	}
+
+	if( isr & AT91C_EMAC_TCOMP )
+	{
+		/* A frame has been transmitted. Mark all the buffers as free */
+		sam7xether_reset_tx_desc();
+
+		AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
+	}
+}
+
+rt_inline void linksetup(void)
+{
+	rt_uint32_t value;
+
+	/* Check if this is a RTL8201 PHY. */
+	rt_uint16_t id1 = read_phy(PHY_REG_PHYID1);
+	rt_uint16_t id2 = read_phy(PHY_REG_PHYID2);
+
+	if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
+	{
+		rt_uint32_t tout;
+
+		/* Configure the PHY device */
+		/* Use autonegotiation about the link speed. */
+		write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
+
+		/* Wait to complete Auto_Negotiation. */
+		for (tout = 0; tout < 0x100000; tout++)
+		{
+			value = read_phy (PHY_REG_BMSR);
+			if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
+		}
+
+		/* Check the link status. */
+		for (tout = 0; tout < 0x10000; tout++)
+		{
+			value = read_phy (PHY_REG_BMSR);
+			if (value & BMSR_LINKST) break; /* Link is on. */
+		}
+	}
+
+	value = read_phy (PHY_REG_ANLPAR);
+
+	/* Update the MAC register NCFGR. */
+	AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+
+	/* set full duplex . */
+	if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
+	/* set speed */
+	if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
+}
+
+/*
+ * Set the MAC address.
+ */
+rt_inline void update_mac_address(struct net_device* device)
+{
+	AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
+								 (device->dev_addr[2] << 16) |
+								 (device->dev_addr[1] << 8)  |
+								 device->dev_addr[0];
+	AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
+								 device->dev_addr[4];
+}
+
+rt_inline void sam7xether_desc_init()
+{
+	rt_uint32_t i;
+
+	/* Rx Buffer Descriptor initialization */
+	current_rb_index = 0;
+	for (i = 0; i < RB_BUFFER_SIZE; i++)
+	{
+		rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
+		rb_descriptors[i].status = 0;
+	}
+	/* Set the WRAP bit at the end of the list descriptor. */
+	rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
+	/* Set Rx Queue pointer to descriptor list. */
+	AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
+
+	/* Tx Buffer Descriptor initialization */
+	for (i = 0; i < TB_BUFFER_SIZE; i++)
+	{
+		tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
+		tb_descriptors[i].status = TxDESC_STATUS_USED;
+	}
+	/* Set the WRAP bit at the end of the list descriptor. */
+	tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
+	/* Set Tx Queue pointer to descriptor list. */
+	AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
+}
+
+/* RT-Thread Device Interface */
+
+/* initialize the interface */
+rt_err_t sam7xether_init(rt_device_t dev)
+{
+	/* enable peripheral clock for EMAC and PIO B */
+	AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
+
+	/* Disable pull up on RXDV => PHY normal mode (not in test mode), */
+	/* and set MII mode. PHY has internal pull down.                  */
+	AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
+
+	/* Clear PB18 <=> PHY powerdown */
+	AT91C_BASE_PIOB->PIO_PER 	= 1<<18;
+	AT91C_BASE_PIOB->PIO_OER 	= 1<<18;
+	AT91C_BASE_PIOB->PIO_CODR 	= 1<<18;
+
+	/* EMAC IO init for EMAC-PHY communication. */
+	AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
+	AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
+
+	/* Enable communication between EMAC-PHY. */
+	AT91C_BASE_EMAC->EMAC_NCR   |= AT91C_EMAC_MPE;
+	/* MDC = MCK/32 */
+	AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
+
+	/* Reset PHY */
+	AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
+
+	AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
+	AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
+	while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL));
+
+	linksetup();
+
+	/* Disable management port in MAC control register. */
+	AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
+
+	/* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
+	AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
+
+	/* Transmit and Receive disable. */
+	AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
+
+	/* init descriptor */
+	sam7xether_desc_init();
+
+	/* Clear receive and transmit status registers. */
+	AT91C_BASE_EMAC->EMAC_RSR  = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+	AT91C_BASE_EMAC->EMAC_TSR  = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
+								  AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
+
+	/* Configure EMAC operation mode. */
+	AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
+	AT91C_BASE_EMAC->EMAC_NCR   |= (AT91C_EMAC_TE  | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
+
+	/* update MAC address */
+	update_mac_address(sam7x_dev);
+
+	/* enable interrupt */
+	AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
+
+	/* setup interrupt */
+	rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL);
+	*(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
+	// AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
+	rt_hw_interrupt_umask(AT91C_ID_EMAC);
+
+	return RT_EOK;
+}
+
+/* control the interface */
+rt_err_t sam7xether_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	switch(cmd)
+	{
+	case NIOCTL_GADDR:
+		/* get mac address */
+		if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
+		else return -RT_ERROR;
+		break;
+
+	default :
+		break;
+	}
+
+	return RT_EOK;
+}
+
+/* Open the ethernet interface */
+rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
+{
+	return RT_EOK;
+}
+
+/* Close the interface */
+rt_err_t sam7xether_close(rt_device_t dev)
+{
+	return RT_EOK;
+}
+
+/* Read */
+rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_set_errno(-RT_ENOSYS);
+	return 0;
+}
+
+/* Write */
+rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	rt_set_errno(-RT_ENOSYS);
+	return 0;
+}
+
+/* See the header file for descriptions of public functions. */
+void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
+{
+	rt_uint8_t *buf_ptr;
+	static rt_uint32_t current_tb_index = 0;
+	rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
+
+	while(tx_offset < length)
+	{
+		/* check whether buffer is available */
+		while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
+		{
+			/* no buffer */
+			rt_thread_delay(5);
+		}
+
+		/* Get the address of the buffer from the descriptor, then copy
+		the data into the buffer. */
+		buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
+
+		/* How much can we write to the buffer? */
+		remain = length - tx_offset;
+		pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
+
+		/* Copy the data into the buffer. */
+		rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
+		tx_offset += pdu_length;
+
+		/* Is this the last data for the frame? */
+		if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
+		else is_last = 0;
+
+		/* Fill out the necessary in the descriptor to get the data sent,
+		then move to the next descriptor, wrapping if necessary. */
+		if(current_tb_index >= (TB_BUFFER_SIZE - 1))
+		{
+			tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
+					| is_last
+					| TxDESC_STATUS_WRAP;
+			current_tb_index = 0;
+		}
+		else
+		{
+			tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
+					| is_last;
+			current_tb_index++;
+		}
+
+		/* If this is the last buffer to be sent for this frame we can
+		start the transmission. */
+		if(is_last)
+		{
+			AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
+		}
+	}
+}
+
+/* ethernet device interface */
+/*
+ * Transmit packet.
+ */
+rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
+{
+	struct pbuf* q;
+
+	/* lock tx operation */
+	rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
+	
+	for (q = p; q != NULL; q = q->next)
+	{
+		if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
+		else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
+	}
+
+	rt_sem_release(&tx_sem);
+
+	return 0;
+}
+
+void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
+{
+	static rt_uint8_t* src_ptr;
+	register rt_uint32_t buf_remain, section_remain;
+	static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
+
+	if(ptr == RT_NULL)
+	{
+		/* Reset our state variables ready for the next read from this buffer. */
+		src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+		frame_read = (rt_uint32_t)0;
+		buf_offset = (rt_uint32_t)0;
+	}
+	else
+	{
+		/* Loop until we have obtained the required amount of data. */
+		section_read = 0;
+		while( section_read < section_length )
+		{
+			buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
+			section_remain = section_length - section_read;
+
+			if( section_remain > buf_remain )
+			{
+				/* more data on section than buffer size */
+				rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
+				section_read += buf_remain;
+				frame_read += buf_remain;
+
+				/* free buffer */
+				rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
+
+				/* move to the next frame. */
+				current_rb_index++;
+				if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
+
+				/* Reset the variables for the new buffer. */
+				src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+				buf_offset = 0;
+			}
+			else
+			{
+				/* more data on buffer than section size */
+				rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
+				buf_offset += section_remain;
+				section_read += section_remain;
+				frame_read += section_remain;
+
+				/* finish this read */
+				if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
+				{
+					/* free buffer */
+					rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
+
+					/* move to the next frame. */
+					current_rb_index++;
+					if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
+
+					src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
+					buf_offset = 0;
+				}
+			}
+		}
+	}
+}
+
+struct pbuf *sam7xether_rx(rt_device_t dev)
+{
+	struct pbuf *p = RT_NULL;
+
+	/* skip fragment frame */
+	while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
+			&& !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
+	{
+		rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
+
+		current_rb_index++;
+		if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
+	}
+
+	if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
+	{
+		struct pbuf* q;
+		rt_uint32_t index, pkt_len = 0;
+
+		/* first of all, find the frame length */
+		index = current_rb_index;
+		while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
+		{
+			pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
+			if (pkt_len > 0) break;
+
+			index ++;
+			if (index > RB_BUFFER_SIZE) index = 0;
+		}
+
+		if (pkt_len)
+		{
+			p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
+			if(p != RT_NULL)
+			{
+				sam7xether_read_frame(RT_NULL, 0, pkt_len);
+				for(q = p; q != RT_NULL; q= q->next)
+					sam7xether_read_frame(q->payload, q->len, pkt_len);
+			}
+			else
+			{
+				rt_kprintf("no memory in pbuf\n");
+			}
+		}
+	}
+
+	/* enable interrupt */
+	AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
+
+	return p;
+}
+
+int sam7xether_register(char *name)
+{
+	rt_err_t result;
+
+	/* init rt-thread device interface */
+	sam7x_dev_entry.parent.parent.init		= sam7xether_init;
+	sam7x_dev_entry.parent.parent.open		= sam7xether_open;
+	sam7x_dev_entry.parent.parent.close		= sam7xether_close;
+	sam7x_dev_entry.parent.parent.read		= sam7xether_read;
+	sam7x_dev_entry.parent.parent.write		= sam7xether_write;
+	sam7x_dev_entry.parent.parent.control	= sam7xether_control;
+	sam7x_dev_entry.parent.eth_rx			= sam7xether_rx;
+	sam7x_dev_entry.parent.eth_tx			= sam7xether_tx;
+
+	/* Update MAC address */
+	sam7x_dev_entry.dev_addr[0] = 0x1e;
+	sam7x_dev_entry.dev_addr[1] = 0x30;
+	sam7x_dev_entry.dev_addr[2] = 0x6c;
+	sam7x_dev_entry.dev_addr[3] = 0xa2;
+	sam7x_dev_entry.dev_addr[4] = 0x45;
+	sam7x_dev_entry.dev_addr[5] = 0x5e;
+	/* update mac address */
+	update_mac_address(sam7x_dev);
+
+	rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
+	
+	result = eth_device_init(&(sam7x_dev->parent), (char*)name);
+	RT_ASSERT(result == RT_EOK);
+
+	return RT_EOK;
+}

+ 64 - 0
libcpu/arm/AT91SAM7X/sam7x_emac.h

@@ -0,0 +1,64 @@
+#ifndef __SAM7X_EMAC_H__
+#define __SAM7X_EMAC_H__
+
+#define AT91C_PHY_ADDR      0x01
+#define MII_RTL8201_ID		0x82010000
+
+/* RTL8201 PHY registers. */
+#define PHY_REG_BMCR        0x00        /* Basic mode control register       */
+#define PHY_REG_BMSR        0x01        /* Basic mode status register        */
+#define PHY_REG_PHYID1      0x02        /* PHY ID identifier #1              */
+#define PHY_REG_PHYID2      0x03        /* PHY ID identifier #2              */
+#define PHY_REG_ANAR        0x04        /* AutoNegotiation Advertisement reg.*/
+#define PHY_REG_ANLPAR      0x05        /* AutoNeg.Link partner ability reg  */
+#define PHY_REG_ANER        0x06        /* AutoNeg. Expansion register       */
+#define PHY_REG_DSCR        0x10        /* DAVICOM Specified Config. reg     */
+#define PHY_REG_DSCSR       0x11        /* DAVICOM Spec. Config/Status reg   */
+#define PHY_REG_10BTCSR     0x12        /* 10BASET Configuration/Status reg  */
+#define PHY_REG_PWDOR       0x13        /* Power Down Control Register       */
+#define PHY_REG_SCR         0x14        /* Specified Config register         */
+#define PHY_REG_INTR        0x15        /* Interrupt register                */
+#define PHY_REG_RECR        0x16        /* Receive Error Counter register    */
+#define PHY_REG_DISCR       0x17        /* Disconnect Counter register       */
+#define PHY_REG_RLSR        0x18        /* Hardware Reset Latch State reg.   */
+
+#define PHY_FULLD_100M      0x2100      /* Full Duplex 100Mbit               */
+#define PHY_HALFD_100M      0x2000      /* Half Duplex 100Mbit               */
+#define PHY_FULLD_10M       0x0100      /* Full Duplex 10Mbit                */
+#define PHY_HALFD_10M       0x0000      /* Half Duplex 10MBit                */
+#define PHY_AUTO_NEG        0x3000      /* Select Auto Negotiation           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP          0x0001      /* Ext-reg capability                */
+#define BMSR_JCD            0x0002      /* Jabber detected                   */
+#define BMSR_LINKST         0x0004      /* Link status                       */
+#define BMSR_ANEGCAPABLE    0x0008      /* Able to do auto-negotiation       */
+#define BMSR_RFAULT         0x0010      /* Remote fault detected             */
+#define BMSR_ANEGCOMPLETE   0x0020      /* Auto-negotiation complete         */
+#define BMSR_MIIPRESUP      0x0040      /* MII Frame Preamble Suppression    */
+#define BMSR_RESV           0x0780      /* Unused...                         */
+#define BMSR_10HALF         0x0800      /* Can do 10mbps, half-duplex        */
+#define BMSR_10FULL         0x1000      /* Can do 10mbps, full-duplex        */
+#define BMSR_100HALF        0x2000      /* Can do 100mbps, half-duplex       */
+#define BMSR_100FULL        0x4000      /* Can do 100mbps, full-duplex       */
+#define BMSR_100BASE4       0x8000      /* Can do 100mbps, 4k packets        */
+
+#define RxDESC_FLAG_ADDR_MASK		0xfffffffc
+#define	RxDESC_FLAG_WARP			0x00000002
+#define	RxDESC_FLAG_OWNSHIP			0x00000001
+#define RxDESC_STATUS_BUF_SIZE		(0x00000FFF)
+#define RxDESC_STATUS_FRAME_START	(1U << 14)
+#define RxDESC_STATUS_FRAME_END		(1U << 15)
+
+#define TxDESC_STATUS_BUF_SIZE		(0x000007FF)
+#define TxDESC_STATUS_LAST_BUF		(1U << 15)
+#define	TxDESC_STATUS_NO_CRC		(1U << 16)
+#define	TxDESC_STATUS_BUF_EXHAUSTED	(1U << 27)
+#define	TxDESC_STATUS_Tx_UNDERRUN	(1U << 28)
+#define	TxDESC_STATUS_Tx_ERROR		(1U << 29)
+#define	TxDESC_STATUS_WRAP			(1U << 30)
+#define	TxDESC_STATUS_USED			(1U << 31)
+
+int sam7xether_register(char *name);
+
+#endif

+ 396 - 0
libcpu/arm/AT91SAM7X/serial.c

@@ -0,0 +1,396 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ * 2009-05-14     Bernard      add RT-THread device interface
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "AT91SAM7X.h"
+#include "serial.h"
+
+/**
+ * @addtogroup AT91SAM7X256
+ */
+/*@{*/
+typedef volatile rt_uint32_t REG32;
+struct rt_at91serial_hw
+{
+	REG32	 US_CR; 	// Control Register
+	REG32	 US_MR; 	// Mode Register
+	REG32	 US_IER; 	// Interrupt Enable Register
+	REG32	 US_IDR; 	// Interrupt Disable Register
+	REG32	 US_IMR; 	// Interrupt Mask Register
+	REG32	 US_CSR; 	// Channel Status Register
+	REG32	 US_RHR; 	// Receiver Holding Register
+	REG32	 US_THR; 	// Transmitter Holding Register
+	REG32	 US_BRGR; 	// Baud Rate Generator Register
+	REG32	 US_RTOR; 	// Receiver Time-out Register
+	REG32	 US_TTGR; 	// Transmitter Time-guard Register
+	REG32	 Reserved0[5]; 	//
+	REG32	 US_FIDI; 	// FI_DI_Ratio Register
+	REG32	 US_NER; 	// Nb Errors Register
+	REG32	 Reserved1[1]; 	//
+	REG32	 US_IF; 	// IRDA_FILTER Register
+	REG32	 Reserved2[44]; 	//
+	REG32	 US_RPR; 	// Receive Pointer Register
+	REG32	 US_RCR; 	// Receive Counter Register
+	REG32	 US_TPR; 	// Transmit Pointer Register
+	REG32	 US_TCR; 	// Transmit Counter Register
+	REG32	 US_RNPR; 	// Receive Next Pointer Register
+	REG32	 US_RNCR; 	// Receive Next Counter Register
+	REG32	 US_TNPR; 	// Transmit Next Pointer Register
+	REG32	 US_TNCR; 	// Transmit Next Counter Register
+	REG32	 US_PTCR; 	// PDC Transfer Control Register
+	REG32	 US_PTSR; 	// PDC Transfer Status Register
+};
+
+struct rt_at91serial
+{
+	struct rt_device parent;
+
+	struct rt_at91serial_hw* hw_base;
+	rt_uint16_t peripheral_id;
+	rt_uint32_t baudrate;
+
+	/* reception field */
+	rt_uint16_t save_index, read_index;
+	rt_uint8_t  rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+#ifdef RT_USING_UART1
+struct rt_at91serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_at91serial serial2;
+#endif
+
+static void rt_hw_serial_isr(int irqno)
+{
+	rt_base_t level;
+	struct rt_device* device;
+	struct rt_at91serial* serial = RT_NULL;
+
+#ifdef RT_USING_UART1
+	if (irqno == AT91C_ID_US0)
+	{
+		/* serial 1 */
+		serial = &serial1;
+	}
+#endif
+
+#ifdef RT_USING_UART2
+	if (irqno == AT91C_ID_US1)
+	{
+		/* serial 2 */
+		serial = &serial2;
+	}
+#endif
+	RT_ASSERT(serial != RT_NULL);
+
+	/* get generic device object */
+	device = (rt_device_t)serial;
+
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	/* get received character */
+	serial->rx_buffer[serial->save_index] = serial->hw_base->US_RHR;
+
+	/* move to next position */
+	serial->save_index ++;
+	if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+		serial->save_index = 0;
+
+	/* if the next position is read index, discard this 'read char' */
+	if (serial->save_index == serial->read_index)
+	{
+		serial->read_index ++;
+		if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+			serial->read_index = 0;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+
+	/* indicate to upper layer application */
+	if (device->rx_indicate != RT_NULL)
+		device->rx_indicate(device, 1);
+
+	/* ack interrupt */
+	AT91C_AIC_EOICR = 1;
+}
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	rt_uint32_t bd;
+	struct rt_at91serial* serial = (struct rt_at91serial*) dev;
+
+	RT_ASSERT(serial != RT_NULL);
+	/* must be US0 or US1 */
+	RT_ASSERT((serial->peripheral_id != AT91C_ID_US0) &&
+			  (serial->peripheral_id != AT91C_ID_US1));
+
+	/* Enable Clock for USART */
+	AT91C_PMC_PCER = 1 << serial->peripheral_id;
+
+	/* Enable RxD0 and TxDO Pin */
+	if (serial->peripheral_id == AT91C_ID_US0)
+	{
+		/* set pinmux */
+		AT91C_PIO_PDR = (1 << 5) | (1 << 6);
+	}
+	else if (serial->peripheral_id == AT91C_ID_US1)
+	{
+		/* set pinmux */
+		AT91C_PIO_PDR = (1 << 21) | (1 << 22);
+	}
+
+	serial->hw_base->US_CR = AT91C_US_RSTRX	    | 	/* Reset Receiver      */
+							 AT91C_US_RSTTX		|	/* Reset Transmitter   */
+							 AT91C_US_RXDIS		|	/* Receiver Disable    */
+							 AT91C_US_TXDIS;		/* Transmitter Disable */
+
+	serial->hw_base->US_MR = AT91C_US_USMODE_NORMAL |	/* Normal Mode */
+							 AT91C_US_CLKS_CLOCK	|	/* Clock = MCK */
+							 AT91C_US_CHRL_8_BITS	|	/* 8-bit Data  */
+							 AT91C_US_PAR_NONE		|	/* No Parity   */
+							 AT91C_US_NBSTOP_1_BIT;		/* 1 Stop Bit  */
+
+	/* set baud rate divisor */
+	bd =  ((MCK*10)/(serial->baudrate * 16));
+	if ((bd % 10) >= 5) bd = (bd / 10) + 1;
+	else bd /= 10;
+
+	serial->hw_base->US_BRGR = bd;
+	serial->hw_base->US_CR = AT91C_US_RXEN |	/* Receiver Enable     */
+							 AT91C_US_TXEN;	    /* Transmitter Enable  */
+
+	/* reset rx index */
+	serial->save_index = 0;
+	serial->read_index = 0;
+
+	/* reset rx buffer */
+	rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* enable UART rx interrupt */
+		serial->hw_base->US_IER = 1 << 0; 		/* RxReady interrupt */
+		serial->hw_base->US_IMR |= 1 << 0; 		/* umask RxReady interrupt */
+
+		/* install UART handler */
+		rt_hw_interrupt_install(serial->peripheral_id, rt_hw_serial_isr, RT_NULL);
+		AT91C_AIC_SMR(serial->peripheral_id) = 5 | (0x01 << 5);
+		rt_hw_interrupt_umask(serial->peripheral_id);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* disable interrupt */
+		serial->hw_base->US_IDR = 1 << 0; 		/* RxReady interrupt */
+		serial->hw_base->US_IMR &= ~(1 << 0); 	/* mask RxReady interrupt */
+	}
+
+	serial->hw_base->US_CR = AT91C_US_RSTRX	    | 	/* Reset Receiver      */
+							 AT91C_US_RSTTX		|	/* Reset Transmitter   */
+							 AT91C_US_RXDIS		|	/* Receiver Disable    */
+							 AT91C_US_TXDIS;		/* Transmitter Disable */
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (serial->read_index != serial->save_index)
+			{
+				*ptr = serial->rx_buffer[serial->read_index];
+
+				serial->read_index ++;
+				if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					serial->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++;
+			size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+	{
+		/* not support right now */
+		RT_ASSERT(0);
+	}
+	else
+	{
+		/* poll mode */
+		while (size)
+		{
+			/* Wait for Full Rx Buffer */
+			while (!(serial->hw_base->US_CSR & AT91C_US_RXRDY));
+
+			/* Read Character */
+			*ptr = serial->hw_base->US_RHR;
+			ptr ++;
+			size --;
+		}
+
+		return (rt_size_t)ptr - (rt_size_t)buffer;
+	}
+
+	return 0;
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_at91serial *serial = (struct rt_at91serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	ptr = (rt_uint8_t*) buffer;
+	if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+	{
+		if (dev->flag & RT_DEVICE_FLAG_STREAM)
+		{
+			/* it's a stream mode device */
+			while (size)
+			{
+				/* stream mode */
+				if (*ptr == '\n')
+				{
+					while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+					serial->hw_base->US_THR = '\r';
+				}
+
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+				/* Transmit Character */
+				serial->hw_base->US_THR = *ptr;
+				ptr ++;
+				size --;
+			}
+		}
+		else
+		{
+			while (size)
+			{
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->US_CSR & AT91C_US_TXRDY));
+
+				/* Transmit Character */
+				serial->hw_base->US_THR = *ptr;
+				ptr ++;
+				size --;
+			}
+		}
+	}
+
+	return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	return RT_EOK;
+}
+
+rt_err_t rt_hw_serial_init()
+{
+	rt_device_t device;
+
+#ifdef RT_USING_UART1
+	device = (rt_device_t) &serial1;
+
+	/* init serial device private data */
+	serial1.hw_base 		= (struct rt_at91serial_hw*)AT91C_BASE_US0;
+	serial1.peripheral_id 	= AT91C_ID_US0;
+	serial1.baudrate		= 115200;
+
+	/* set device virtual interface */
+	device->init 	= rt_serial_init;
+	device->open 	= rt_serial_open;
+	device->close 	= rt_serial_close;
+	device->read 	= rt_serial_read;
+	device->write 	= rt_serial_write;
+	device->control = rt_serial_control;
+
+	/* register uart1 on device subsystem */
+	rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+	device = (rt_device_t) &serial2;
+
+	serial2.hw_base 		= (struct rt_at91serial_hw*)AT91C_BASE_US1;
+	serial2.peripheral_id 	= AT91C_ID_US1;
+	serial2.baudrate		= 115200;
+
+	/* set device virtual interface */
+	device->init 	= rt_serial_init;
+	device->open 	= rt_serial_open;
+	device->close 	= rt_serial_close;
+	device->read 	= rt_serial_read;
+	device->write 	= rt_serial_write;
+	device->control = rt_serial_control;
+
+	/* register uart2 on device subsystem */
+	rt_device_register(device, "uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+	return RT_EOK;
+}
+
+/*@}*/

+ 56 - 0
libcpu/arm/AT91SAM7X/serial.h

@@ -0,0 +1,56 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+
+#ifndef AT91C_BASE_US0
+#define AT91C_BASE_US0            (0xFFFC0000) // (US0) Base Address
+#endif
+
+#ifndef AT91C_BASE_US1
+#define AT91C_BASE_US1            (0xFFFC4000) // (US1) Base Address
+#endif
+
+#define AT91C_US_RXRDY			((unsigned int) 0x1 <<  0)	/* US RXRDY Interrupt */
+#define AT91C_US_TXRDY			((unsigned int) 0x1 <<  1)	/* US TXRDY Interrupt */
+#define AT91C_US_RSTRX			((unsigned int) 0x1 <<  2)	/* US Reset Receiver */
+#define AT91C_US_RSTTX			((unsigned int) 0x1 <<  3)	/* US Reset Transmitter */
+#define AT91C_US_RXEN			((unsigned int) 0x1 <<  4)	/* US Receiver Enable */
+#define AT91C_US_RXDIS			((unsigned int) 0x1 <<  5)	/* US Receiver Disable */
+#define AT91C_US_TXEN			((unsigned int) 0x1 <<  6)	/* US Transmitter Enable */
+#define AT91C_US_TXDIS			((unsigned int) 0x1 <<  7)	/* US Transmitter Disable */
+#define AT91C_US_RSTSTA			((unsigned int) 0x1 <<  8)	/* US Reset Status Bits */
+
+#define AT91C_US_USMODE_NORMAL	((unsigned int) 0x0)		/* USAR) Normal */
+#define AT91C_US_USMODE_RS485	((unsigned int) 0x1)		/* USAR) RS485 */
+#define AT91C_US_USMODE_HWHSH	((unsigned int) 0x2)		/* USAR) Hardware Handshaking */
+#define AT91C_US_USMODE_MODEM	((unsigned int) 0x3)		/* USAR) Modem */
+#define AT91C_US_USMODE_ISO7816_0	((unsigned int) 0x4)	/* USAR) ISO7816 protocol: T = 0 */
+#define AT91C_US_USMODE_ISO7816_1	((unsigned int) 0x6)	/* USAR) ISO7816 protocol: T = 1 */
+#define AT91C_US_USMODE_IRDA	((unsigned int) 0x8)		/* USAR) IrDA */
+#define AT91C_US_USMODE_SWHSH	((unsigned int) 0xC)		/* USAR) Software Handshaking */
+
+#define AT91C_US_CLKS_CLOCK		((unsigned int) 0x0 <<  4)	/* USAR) Clock */
+#define AT91C_US_CLKS_FDIV1		((unsigned int) 0x1 <<  4)	/* USAR) fdiv1 */
+#define AT91C_US_CLKS_SLOW		((unsigned int) 0x2 <<  4)	/* USAR) slow_clock (ARM) */
+#define AT91C_US_CLKS_EXT		((unsigned int) 0x3 <<  4)	/* USAR) External (SCK) */
+
+#define AT91C_US_CHRL_5_BITS	((unsigned int) 0x0 <<  6)	/* USAR) Character Length: 5 bits */
+#define AT91C_US_CHRL_6_BITS	((unsigned int) 0x1 <<  6)	/* USAR) Character Length: 6 bits */
+#define AT91C_US_CHRL_7_BITS	((unsigned int) 0x2 <<  6)	/* USAR) Character Length: 7 bits */
+#define AT91C_US_CHRL_8_BITS	((unsigned int) 0x3 <<  6)	/* USAR) Character Length: 8 bits */
+
+#define AT91C_US_PAR_EVEN		((unsigned int) 0x0 <<  9)	/* DBGU Even Parity */
+#define AT91C_US_PAR_ODD		((unsigned int) 0x1 <<  9)	/* DBGU Odd Parity */
+#define AT91C_US_PAR_SPACE		((unsigned int) 0x2 <<  9)	/* DBGU Parity forced to 0 (Space) */
+#define AT91C_US_PAR_MARK		((unsigned int) 0x3 <<  9)	/* DBGU Parity forced to 1 (Mark) */
+#define AT91C_US_PAR_NONE		((unsigned int) 0x4 <<  9)	/* DBGU No Parity */
+#define AT91C_US_PAR_MULTI_DROP	((unsigned int) 0x6 <<  9)	/* DBGU Multi-drop mode */
+
+#define AT91C_US_NBSTOP_1_BIT	((unsigned int) 0x0 << 12)	/* USART 1 stop bit */
+#define AT91C_US_NBSTOP_15_BIT	((unsigned int) 0x1 << 12)	/* USART Asynchronous (SYNC=0) 2 stop bits Synchronous (SYNC=1) 2 stop bits */
+#define AT91C_US_NBSTOP_2_BIT	((unsigned int) 0x2 << 12)	/* USART 2 stop bits */
+
+#define MCK		48054857
+#define BR    	115200			/* Baud Rate */
+#define BRD  	(MCK/16/BR)		/* Baud Rate Divisor */
+
+#endif

+ 60 - 0
libcpu/arm/AT91SAM7X/stack.c

@@ -0,0 +1,60 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      the first version
+ */
+#include <rtthread.h>
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk) 	 = (unsigned long)tentry;		/* entry point */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 235 - 0
libcpu/arm/AT91SAM7X/start_gcc.S

@@ -0,0 +1,235 @@
+/*
+ * File      : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-31     Bernard      first version
+ */
+
+	/* Internal Memory Base Addresses */
+	.equ    FLASH_BASE,     0x00100000   
+	.equ    RAM_BASE,       0x00200000
+
+	/* Stack Configuration */
+	.equ    TOP_STACK,      0x00204000
+	.equ    UND_STACK_SIZE, 0x00000100
+	.equ    SVC_STACK_SIZE, 0x00000400
+	.equ    ABT_STACK_SIZE, 0x00000100
+	.equ    FIQ_STACK_SIZE, 0x00000100
+	.equ    IRQ_STACK_SIZE, 0x00000100
+	.equ    USR_STACK_SIZE, 0x00000004
+
+	/* ARM architecture definitions */
+	.equ	MODE_USR, 0x10
+	.equ	MODE_FIQ, 0x11
+	.equ	MODE_IRQ, 0x12
+	.equ	MODE_SVC, 0x13
+	.equ	MODE_ABT, 0x17
+	.equ	MODE_UND, 0x1B
+	.equ	MODE_SYS, 0x1F
+
+	.equ    I_BIT, 0x80    /* when this bit is set, IRQ is disabled */
+	.equ    F_BIT, 0x40    /* when this bit is set, FIQ is disabled */
+
+.section .init, "ax"
+.code 32
+.align 0
+.globl _start
+_start:
+	b	reset
+	ldr	pc, _vector_undef
+	ldr	pc, _vector_swi
+	ldr	pc, _vector_pabt
+	ldr	pc, _vector_dabt
+	nop							/* reserved vector */
+	ldr	pc, _vector_irq
+	ldr	pc, _vector_fiq
+
+_vector_undef:	.word vector_undef
+_vector_swi:	.word vector_swi
+_vector_pabt:	.word vector_pabt
+_vector_dabt:	.word vector_dabt
+_vector_resv:	.word vector_resv
+_vector_irq:	.word vector_irq
+_vector_fiq:	.word vector_fiq
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start:	.word __bss_start
+.globl _bss_end
+_bss_end:	.word __bss_end
+
+/* the system entry */
+reset:
+	/* disable watchdog */
+	ldr r0, =0xFFFFFD40
+	ldr r1, =0x00008000
+	str r1, [r0, #0x04]
+	
+	/* enable the main oscillator */
+	ldr r0, =0xFFFFFC00
+	ldr r1, =0x00000601
+	str r1, [r0, #0x20]
+	
+	/* wait for main oscillator to stabilize */
+moscs_loop:
+	ldr r2, [r0, #0x68]
+	ands r2, r2, #1
+	beq moscs_loop
+	
+	/* set up the PLL */
+	ldr r1, =0x00191C05
+	str r1, [r0, #0x2C]
+	
+	/* wait for PLL to lock */
+pll_loop:
+	ldr r2, [r0, #0x68]
+	ands r2, r2, #0x04
+	beq pll_loop
+	
+	/* select clock */
+	ldr r1, =0x00000007
+	str r1, [r0, #0x30]
+	
+#ifdef __FLASH_BUILD__
+	/* copy exception vectors into internal sram */
+	mov r8, #RAM_BASE
+	ldr r9, =_start
+	ldmia r9!, {r0-r7}
+	stmia r8!, {r0-r7}
+	ldmia r9!, {r0-r6}
+	stmia r8!, {r0-r6}
+#endif
+	
+	/* setup stack for each mode */
+	ldr r0, =TOP_STACK
+	
+	/* set stack */
+	/* undefined instruction mode */
+	msr cpsr_c, #MODE_UND|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #UND_STACK_SIZE
+	
+	/* abort mode */
+	msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #ABT_STACK_SIZE
+	
+	/* FIQ mode */
+	msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #FIQ_STACK_SIZE
+	
+	/* IRQ mode */
+	msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
+	mov sp, r0
+	sub r0, r0, #IRQ_STACK_SIZE
+	
+	/* supervisor mode */
+	msr cpsr_c, #MODE_SVC
+	mov sp, r0
+	
+	/* remap SRAM to 0x0000 */
+	ldr r0, =0xFFFFFF00
+	mov r1, #0x01
+	str r1, [r0]
+	
+	/* mask all IRQs */
+	ldr	r1, =0xFFFFF124
+	ldr	r0, =0XFFFFFFFF
+	str	r0, [r1]
+	
+	/* start RT-Thread Kernel */
+	ldr	pc, _rtthread_startup
+	
+_rtthread_startup: .word rtthread_startup
+
+/* exception handlers */
+vector_undef: b	vector_undef
+vector_swi  : b vector_swi
+vector_pabt : b vector_pabt
+vector_dabt : b vector_dabt
+vector_resv : b vector_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:
+	stmfd	sp!, {r0-r12,lr}
+	bl	rt_interrupt_enter
+	bl	rt_hw_trap_irq
+	bl	rt_interrupt_leave
+
+	/* 
+	 * if rt_thread_switch_interrput_flag set, jump to
+	 * rt_hw_context_switch_interrupt_do and don't return
+	 */
+	ldr	r0, =rt_thread_switch_interrput_flag
+	ldr	r1, [r0]
+	cmp	r1, #1
+	beq	rt_hw_context_switch_interrupt_do
+
+	ldmfd	sp!, {r0-r12,lr}
+	subs	pc, lr, #4
+
+vector_fiq:
+	stmfd	sp!,{r0-r7,lr}
+	bl 	rt_hw_trap_fiq
+	ldmfd	sp!,{r0-r7,lr}
+	subs	pc,lr,#4
+
+/*
+ * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+ */
+rt_hw_context_switch_interrupt_do:
+	mov	r1,  #0				@ clear flag
+	str	r1,  [r0]
+
+	ldmfd	sp!, {r0-r12,lr}@ reload saved registers
+	stmfd	sp!, {r0-r3}	@ save r0-r3
+	mov	r1,  sp
+	add	sp,  sp, #16		@ restore sp
+	sub	r2,  lr, #4			@ save old task's pc to r2
+
+	mrs	r3,  spsr			@ disable interrupt
+	orr	r0,  r3, #I_BIT|F_BIT
+	msr	spsr_c, r0
+
+	ldr	r0,  =.+8			@ switch to interrupted task's stack
+	movs	pc,  r0
+
+	stmfd	sp!, {r2}		@ push old task's pc
+	stmfd	sp!, {r4-r12,lr}@ push old task's lr,r12-r4
+	mov	r4,  r1				@ Special optimised code below
+	mov	r5,  r3
+	ldmfd	r4!, {r0-r3}
+	stmfd	sp!, {r0-r3}	@ push old task's r3-r0
+	stmfd	sp!, {r5}		@ push old task's psr
+	mrs	r4,  spsr
+	stmfd	sp!, {r4}		@ push old task's spsr
+
+	ldr	r4,  =rt_interrupt_from_thread
+	ldr	r5,  [r4]
+	str	sp,  [r5]			@ store sp in preempted tasks's TCB
+
+	ldr	r6,  =rt_interrupt_to_thread
+	ldr	r6,  [r6]
+	ldr	sp,  [r6]			@ get new task's stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task's spsr
+	msr	SPSR_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task's psr
+	msr	CPSR_cxsf, r4
+
+	ldmfd	sp!, {r0-r12,lr,pc}	@ pop new task's r0-r12,lr & pc

+ 498 - 0
libcpu/arm/AT91SAM7X/start_rvds.S

@@ -0,0 +1,498 @@
+;/*****************************************************************************/
+;/* SAM7.S: Startup file for Atmel AT91SAM7 device series                     */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>>                          */ 
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools.                   */
+;/* Copyright (c) 2005-2006 Keil Software. All rights reserved.               */
+;/* This software may only be used under the terms of a valid, current,       */
+;/* end user licence from KEIL for a compatible version of KEIL software      */
+;/* development tools. Nothing else gives you the right to use this software. */
+;/*****************************************************************************/
+
+
+;/*
+; *  The SAM7.S code is executed after CPU Reset. This file may be 
+; *  translated with the following SET symbols. In uVision these SET 
+; *  symbols are entered under Options - ASM - Define.
+; *
+; *  REMAP: when set the startup code remaps exception vectors from
+; *  on-chip RAM to address 0.
+; *
+; *  RAM_INTVEC: when set the startup code copies exception vectors 
+; *  from on-chip Flash to on-chip RAM.
+; */
+
+
+; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+
+Mode_USR        EQU     0x10
+Mode_FIQ        EQU     0x11
+Mode_IRQ        EQU     0x12
+Mode_SVC        EQU     0x13
+Mode_ABT        EQU     0x17
+Mode_UND        EQU     0x1B
+Mode_SYS        EQU     0x1F
+
+I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
+F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
+
+
+; Internal Memory Base Addresses
+FLASH_BASE      EQU     0x00100000   
+RAM_BASE        EQU     0x00200000
+
+
+;// <h> Stack Configuration (Stack Sizes in Bytes)
+;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
+;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
+;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
+;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
+;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
+;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
+;// </h>
+
+UND_Stack_Size  EQU     0x00000000
+SVC_Stack_Size  EQU     0x00000100
+ABT_Stack_Size  EQU     0x00000000
+FIQ_Stack_Size  EQU     0x00000000
+IRQ_Stack_Size  EQU     0x00000100
+USR_Stack_Size  EQU     0x00000100
+
+ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                         FIQ_Stack_Size + IRQ_Stack_Size)
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem       SPACE   USR_Stack_Size
+__initial_sp    SPACE   ISR_Stack_Size
+Stack_Top
+
+
+;// <h> Heap Configuration
+;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
+;// </h>
+
+Heap_Size       EQU     0x00000000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+; Reset Controller (RSTC) definitions
+RSTC_BASE       EQU     0xFFFFFD00      ; RSTC Base Address
+RSTC_MR         EQU     0x08            ; RSTC_MR Offset
+
+;/*
+;// <e> Reset Controller (RSTC)
+;//   <o1.0>     URSTEN: User Reset Enable
+;//              <i> Enables NRST Pin to generate Reset
+;//   <o1.8..11> ERSTL: External Reset Length <0-15>
+;//              <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
+;// </e>
+;*/
+RSTC_SETUP      EQU     1
+RSTC_MR_Val     EQU     0xA5000401
+
+
+; Embedded Flash Controller (EFC) definitions
+EFC_BASE        EQU     0xFFFFFF00      ; EFC Base Address
+EFC0_FMR        EQU     0x60            ; EFC0_FMR Offset
+EFC1_FMR        EQU     0x70            ; EFC1_FMR Offset
+
+;// <e> Embedded Flash Controller 0 (EFC0)
+;//   <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;//               <i> Number of Master Clock Cycles in 1us
+;//   <o1.8..9>   FWS: Flash Wait State
+;//               <0=> Read: 1 cycle / Write: 2 cycles
+;//               <1=> Read: 2 cycle / Write: 3 cycles
+;//               <2=> Read: 3 cycle / Write: 4 cycles
+;//               <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC0_SETUP      EQU     1
+EFC0_FMR_Val    EQU     0x00320100
+
+;// <e> Embedded Flash Controller 1 (EFC1)
+;//   <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
+;//               <i> Number of Master Clock Cycles in 1us
+;//   <o1.8..9>   FWS: Flash Wait State
+;//               <0=> Read: 1 cycle / Write: 2 cycles
+;//               <1=> Read: 2 cycle / Write: 3 cycles
+;//               <2=> Read: 3 cycle / Write: 4 cycles
+;//               <3=> Read: 4 cycle / Write: 4 cycles
+;// </e>
+EFC1_SETUP      EQU     0
+EFC1_FMR_Val    EQU     0x00320100
+
+
+; Watchdog Timer (WDT) definitions
+WDT_BASE        EQU     0xFFFFFD40      ; WDT Base Address
+WDT_MR          EQU     0x04            ; WDT_MR Offset
+
+;// <e> Watchdog Timer (WDT)
+;//   <o1.0..11>  WDV: Watchdog Counter Value <0-4095>
+;//   <o1.16..27> WDD: Watchdog Delta Value <0-4095>
+;//   <o1.12>     WDFIEN: Watchdog Fault Interrupt Enable
+;//   <o1.13>     WDRSTEN: Watchdog Reset Enable
+;//   <o1.14>     WDRPROC: Watchdog Reset Processor
+;//   <o1.28>     WDDBGHLT: Watchdog Debug Halt
+;//   <o1.29>     WDIDLEHLT: Watchdog Idle Halt
+;//   <o1.15>     WDDIS: Watchdog Disable
+;// </e>
+WDT_SETUP       EQU     1
+WDT_MR_Val      EQU     0x00008000
+
+
+; Power Mangement Controller (PMC) definitions
+PMC_BASE        EQU     0xFFFFFC00      ; PMC Base Address
+PMC_MOR         EQU     0x20            ; PMC_MOR Offset
+PMC_MCFR        EQU     0x24            ; PMC_MCFR Offset
+PMC_PLLR        EQU     0x2C            ; PMC_PLLR Offset
+PMC_MCKR        EQU     0x30            ; PMC_MCKR Offset
+PMC_SR          EQU     0x68            ; PMC_SR Offset
+PMC_MOSCEN      EQU     (1<<0)          ; Main Oscillator Enable
+PMC_OSCBYPASS   EQU     (1<<1)          ; Main Oscillator Bypass
+PMC_OSCOUNT     EQU     (0xFF<<8)       ; Main OScillator Start-up Time
+PMC_DIV         EQU     (0xFF<<0)       ; PLL Divider
+PMC_PLLCOUNT    EQU     (0x3F<<8)       ; PLL Lock Counter
+PMC_OUT         EQU     (0x03<<14)      ; PLL Clock Frequency Range
+PMC_MUL         EQU     (0x7FF<<16)     ; PLL Multiplier
+PMC_USBDIV      EQU     (0x03<<28)      ; USB Clock Divider
+PMC_CSS         EQU     (3<<0)          ; Clock Source Selection
+PMC_PRES        EQU     (7<<2)          ; Prescaler Selection
+PMC_MOSCS       EQU     (1<<0)          ; Main Oscillator Stable
+PMC_LOCK        EQU     (1<<2)          ; PLL Lock Status
+PMC_MCKRDY      EQU     (1<<3)          ; Master Clock Status
+
+;// <e> Power Mangement Controller (PMC)
+;//   <h> Main Oscillator
+;//     <o1.0>      MOSCEN: Main Oscillator Enable
+;//     <o1.1>      OSCBYPASS: Oscillator Bypass
+;//     <o1.8..15>  OSCCOUNT: Main Oscillator Startup Time <0-255>
+;//   </h>
+;//   <h> Phase Locked Loop (PLL)
+;//     <o2.0..7>   DIV: PLL Divider <0-255>
+;//     <o2.16..26> MUL: PLL Multiplier <0-2047>
+;//                 <i> PLL Output is multiplied by MUL+1
+;//     <o2.14..15> OUT: PLL Clock Frequency Range
+;//                 <0=> 80..160MHz  <1=> Reserved
+;//                 <2=> 150..220MHz <3=> Reserved
+;//     <o2.8..13>  PLLCOUNT: PLL Lock Counter <0-63>
+;//     <o2.28..29> USBDIV: USB Clock Divider
+;//                 <0=> None  <1=> 2  <2=> 4  <3=> Reserved
+;//   </h>
+;//   <o3.0..1>   CSS: Clock Source Selection
+;//               <0=> Slow Clock
+;//               <1=> Main Clock
+;//               <2=> Reserved
+;//               <3=> PLL Clock
+;//   <o3.2..4>   PRES: Prescaler
+;//               <0=> None
+;//               <1=> Clock / 2    <2=> Clock / 4
+;//               <3=> Clock / 8    <4=> Clock / 16
+;//               <5=> Clock / 32   <6=> Clock / 64
+;//               <7=> Reserved
+;// </e>
+PMC_SETUP       EQU     1
+PMC_MOR_Val     EQU     0x00000601
+PMC_PLLR_Val    EQU     0x00191C05
+PMC_MCKR_Val    EQU     0x00000007
+
+
+                PRESERVE8
+                
+
+; Area Definition and Entry Point
+;  Startup Code must be linked first at Address at which it expects to run.
+
+                AREA    RESET, CODE, READONLY
+                ARM
+
+
+; Exception Vectors
+;  Mapped to Address 0.
+;  Absolute addressing mode must be used.
+;  Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors         LDR     PC,Reset_Addr         
+                LDR     PC,Undef_Addr
+                LDR     PC,SWI_Addr
+                LDR     PC,PAbt_Addr
+                LDR     PC,DAbt_Addr
+                NOP                            ; Reserved Vector
+                LDR     PC,IRQ_Addr
+                LDR     PC,FIQ_Addr
+
+Reset_Addr      DCD     Reset_Handler
+Undef_Addr      DCD     Undef_Handler
+SWI_Addr        DCD     SWI_Handler
+PAbt_Addr       DCD     PAbt_Handler
+DAbt_Addr       DCD     DAbt_Handler
+                DCD     0                      ; Reserved Address
+IRQ_Addr        DCD     IRQ_Handler
+FIQ_Addr        DCD     FIQ_Handler
+
+Undef_Handler   B       Undef_Handler
+SWI_Handler     B       SWI_Handler
+PAbt_Handler    B       PAbt_Handler
+DAbt_Handler    B       DAbt_Handler
+FIQ_Handler     B       FIQ_Handler
+
+
+; Reset Handler
+
+                EXPORT  Reset_Handler
+Reset_Handler   
+
+
+; Setup RSTC
+                IF      RSTC_SETUP != 0
+                LDR     R0, =RSTC_BASE
+                LDR     R1, =RSTC_MR_Val
+                STR     R1, [R0, #RSTC_MR]
+                ENDIF
+
+
+; Setup EFC0
+                IF      EFC0_SETUP != 0
+                LDR     R0, =EFC_BASE
+                LDR     R1, =EFC0_FMR_Val
+                STR     R1, [R0, #EFC0_FMR]
+                ENDIF
+
+; Setup EFC1
+                IF      EFC1_SETUP != 0
+                LDR     R0, =EFC_BASE
+                LDR     R1, =EFC1_FMR_Val
+                STR     R1, [R0, #EFC1_FMR]
+                ENDIF
+
+; Setup WDT
+                IF      WDT_SETUP != 0
+                LDR     R0, =WDT_BASE
+                LDR     R1, =WDT_MR_Val
+                STR     R1, [R0, #WDT_MR]
+                ENDIF
+
+
+; Setup PMC
+                IF      PMC_SETUP != 0
+                LDR     R0, =PMC_BASE
+
+;  Setup Main Oscillator
+                LDR     R1, =PMC_MOR_Val
+                STR     R1, [R0, #PMC_MOR]
+
+;  Wait until Main Oscillator is stablilized
+                IF      (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
+MOSCS_Loop      LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MOSCS
+                BEQ     MOSCS_Loop
+                ENDIF
+
+;  Setup the PLL
+                IF      (PMC_PLLR_Val:AND:PMC_MUL) != 0
+                LDR     R1, =PMC_PLLR_Val
+                STR     R1, [R0, #PMC_PLLR]
+
+;  Wait until PLL is stabilized
+PLL_Loop        LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_LOCK
+                BEQ     PLL_Loop
+                ENDIF
+
+;  Select Clock
+                IF      (PMC_MCKR_Val:AND:PMC_CSS) == 1     ; Main Clock Selected
+                LDR     R1, =PMC_MCKR_Val
+                AND     R1, #PMC_CSS
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy1       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy1
+                LDR     R1, =PMC_MCKR_Val
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy2       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy2
+                ELIF    (PMC_MCKR_Val:AND:PMC_CSS) == 3     ; PLL  Clock Selected
+                LDR     R1, =PMC_MCKR_Val
+                AND     R1, #PMC_PRES
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy1       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy1
+                LDR     R1, =PMC_MCKR_Val
+                STR     R1, [R0, #PMC_MCKR]
+WAIT_Rdy2       LDR     R2, [R0, #PMC_SR]
+                ANDS    R2, R2, #PMC_MCKRDY
+                BEQ     WAIT_Rdy2
+                ENDIF   ; Select Clock
+                ENDIF   ; PMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM
+
+                IF      :DEF:RAM_INTVEC
+                ADR     R8, Vectors         ; Source
+                LDR     R9, =RAM_BASE       ; Destination
+                LDMIA   R8!, {R0-R7}        ; Load Vectors 
+                STMIA   R9!, {R0-R7}        ; Store Vectors 
+                LDMIA   R8!, {R0-R7}        ; Load Handler Addresses 
+                STMIA   R9!, {R0-R7}        ; Store Handler Addresses
+                ENDIF
+
+
+; Remap on-chip RAM to address 0
+
+MC_BASE EQU     0xFFFFFF00      ; MC Base Address
+MC_RCR  EQU     0x00            ; MC_RCR Offset
+
+                IF      :DEF:REMAP
+                LDR     R0, =MC_BASE
+                MOV     R1, #1
+                STR     R1, [R0, #MC_RCR]   ; Remap
+                ENDIF
+
+
+; Setup Stack for each mode
+
+                LDR     R0, =Stack_Top
+
+;  Enter Undefined Instruction Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #UND_Stack_Size
+
+;  Enter Abort Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #ABT_Stack_Size
+
+;  Enter FIQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #FIQ_Stack_Size
+
+;  Enter IRQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #IRQ_Stack_Size
+
+;  Enter Supervisor Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #SVC_Stack_Size
+
+;  Enter User Mode and set its Stack Pointer
+                ; MSR     CPSR_c, #Mode_USR
+                IF      :DEF:__MICROLIB
+
+                EXPORT __initial_sp
+
+                ELSE
+
+                MOV     SP, R0
+                SUB     SL, SP, #USR_Stack_Size
+
+                ENDIF
+
+
+; Enter the C code
+
+                IMPORT  __main
+                LDR     R0, =__main
+                BX      R0
+
+				IMPORT rt_interrupt_enter
+				IMPORT rt_interrupt_leave
+				IMPORT rt_thread_switch_interrput_flag
+				IMPORT rt_interrupt_from_thread
+				IMPORT rt_interrupt_to_thread
+				IMPORT rt_hw_trap_irq
+				
+IRQ_Handler		PROC
+				EXPORT IRQ_Handler
+				STMFD	sp!, {r0-r12,lr}
+				BL	rt_interrupt_enter
+				BL	rt_hw_trap_irq
+				BL	rt_interrupt_leave
+
+				; if rt_thread_switch_interrput_flag set, jump to
+				; rt_hw_context_switch_interrupt_do and don't return
+				LDR	r0, =rt_thread_switch_interrput_flag
+				LDR	r1, [r0]
+				CMP	r1, #1
+				BEQ	rt_hw_context_switch_interrupt_do
+
+				LDMFD	sp!, {r0-r12,lr}
+				SUBS	pc, lr, #4
+				ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do	PROC
+				EXPORT rt_hw_context_switch_interrupt_do
+				MOV		r1,  #0			; clear flag
+				STR		r1,  [r0]
+
+				LDMFD	sp!, {r0-r12,lr}; reload saved registers
+				STMFD	sp!, {r0-r3}	; save r0-r3
+				MOV		r1,  sp
+				ADD		sp,  sp, #16	; restore sp
+				SUB		r2,  lr, #4		; save old task's pc to r2
+
+				MRS		r3,  spsr		; get cpsr of interrupt thread
+
+				; switch to SVC mode and no interrupt
+                MSR     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+				STMFD	sp!, {r2}		; push old task's pc
+				STMFD	sp!, {r4-r12,lr}; push old task's lr,r12-r4
+				MOV		r4,  r1			; Special optimised code below
+				MOV		r5,  r3
+				LDMFD	r4!, {r0-r3}
+				STMFD	sp!, {r0-r3}	; push old task's r3-r0
+				STMFD	sp!, {r5}		; push old task's cpsr
+				MRS		r4,  spsr
+				STMFD	sp!, {r4}		; push old task's spsr
+
+				LDR		r4,  =rt_interrupt_from_thread
+				LDR		r5,  [r4]
+				STR		sp,  [r5]		; store sp in preempted tasks's TCB
+
+				LDR		r6,  =rt_interrupt_to_thread
+				LDR		r6,  [r6]
+				LDR		sp,  [r6]		; get new task's stack pointer
+			
+				LDMFD	sp!, {r4}		; pop new task's spsr
+				MSR		spsr_cxsf, r4
+				LDMFD	sp!, {r4}		; pop new task's psr
+				MSR		cpsr_cxsf, r4
+
+				LDMFD	sp!, {r0-r12,lr,pc}	; pop new task's r0-r12,lr & pc
+				ENDP
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+; User Initial Stack & Heap
+                AREA    |.text|, CODE, READONLY
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + USR_Stack_Size)
+                LDR     R2, = (Heap_Mem +      Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDIF
+
+                END

+ 40 - 0
libcpu/arm/AT91SAM7X/trap.c

@@ -0,0 +1,40 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-25     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "AT91SAM7X.h"
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+	rt_isr_handler_t hander = (rt_isr_handler_t)AT91C_AIC_IVR;
+
+	hander(AT91C_AIC_ISR);
+
+	/* end of interrupt */
+	AT91C_AIC_EOICR = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+    rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/

+ 67 - 0
libcpu/arm/common/backtrace.c

@@ -0,0 +1,67 @@
+/*
+ * File      : backtrace.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-07-29     Bernard      first version from QiuYi implementation
+ */
+
+#include <rtthread.h>
+
+#ifdef __GNUC__
+/*
+-->High Address,Stack Top
+PC<-----|
+LR	 	 |
+IP	 	 |
+FP	 	 |
+......		 |
+PC<-|	 |
+LR	 |	 |
+IP	 |	 |
+FP---|-- |
+......	 |
+PC	 |
+LR	 |
+IP 	 |
+FP---
+-->Low Address,Stack Bottom
+*/
+void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
+{
+	rt_uint32_t i, pc, func_entry;
+
+	pc = *fp;
+	rt_kprintf("[0x%x]\n", pc-0xC);
+
+	for(i=0; i<10; i++)
+	{
+		fp = *(fp - 3);
+		pc = *fp ;
+
+		func_entry = pc - 0xC;
+
+		if(func_entry <= 0x30000000) break;
+
+		if((func_entry == thread_entry))
+		{
+			rt_kprintf("EntryPoint:0x%x\n", func_entry);
+
+			break;
+		}
+
+		rt_kprintf("[0x%x]\n", func_entry);
+	}
+}
+#else
+void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
+{
+	/* old compiler implementation */
+}
+#endif

+ 4 - 0
libcpu/arm/common/div0.c

@@ -0,0 +1,4 @@
+void __div0 (void)
+{
+	while (1) ;
+}

+ 393 - 0
libcpu/arm/common/divsi3.S

@@ -0,0 +1,393 @@
+/*	$NetBSD: divsi3.S,v 1.5 2005/02/26 22:58:56 perry Exp $	*/
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * stack is aligned as there's a possibility of branching to L_overflow
+ * which makes a C call
+ */
+	.text
+	.align	0
+	.globl	__umodsi3
+	.type	__umodsi3 , function
+__umodsi3:
+	stmfd	sp!, {lr}
+	sub	sp, sp, #4	/* align stack */
+	bl	.L_udivide
+	add	sp, sp, #4	/* unalign stack */
+	mov	r0, r1
+	ldmfd	sp!, {pc}
+
+	.text
+	.align	0
+	.globl	__modsi3
+	.type	__modsi3 , function
+__modsi3:
+	stmfd	sp!, {lr}
+	sub	sp, sp, #4	/* align stack */
+	bl	.L_divide
+	add	sp, sp, #4	/* unalign stack */
+	mov	r0, r1
+	ldmfd	sp!, {pc}
+
+.L_overflow:
+	/* XXX should cause a fatal error */
+	mvn	r0, #0
+	mov	pc, lr
+
+	.text
+	.align	0
+	.globl	__udivsi3
+	.type	__udivsi3 , function
+__udivsi3:
+.L_udivide:				/* r0 = r0 / r1; r1 = r0 % r1 */
+	eor     r0, r1, r0
+	eor     r1, r0, r1
+	eor     r0, r1, r0
+					/* r0 = r1 / r0; r1 = r1 % r0 */
+	cmp	r0, #1
+	bcc	.L_overflow
+	beq	.L_divide_l0
+	mov	ip, #0
+	movs	r1, r1
+	bpl	.L_divide_l1
+	orr	ip, ip, #0x20000000	/* ip bit 0x20000000 = -ve r1 */
+	movs	r1, r1, lsr #1
+	orrcs	ip, ip, #0x10000000	/* ip bit 0x10000000 = bit 0 of r1 */
+	b	.L_divide_l1
+
+.L_divide_l0:				/* r0 == 1 */
+	mov	r0, r1
+	mov	r1, #0
+	mov	pc, lr
+
+	.text
+	.align	0
+	.globl	__divsi3
+	.type	__divsi3 , function
+__divsi3:
+.L_divide:				/* r0 = r0 / r1; r1 = r0 % r1 */
+	eor     r0, r1, r0
+	eor     r1, r0, r1
+	eor     r0, r1, r0
+					/* r0 = r1 / r0; r1 = r1 % r0 */
+	cmp	r0, #1
+	bcc	.L_overflow
+	beq	.L_divide_l0
+	ands	ip, r0, #0x80000000
+	rsbmi	r0, r0, #0
+	ands	r2, r1, #0x80000000
+	eor	ip, ip, r2
+	rsbmi	r1, r1, #0
+	orr	ip, r2, ip, lsr #1	/* ip bit 0x40000000 = -ve division */
+					/* ip bit 0x80000000 = -ve remainder */
+
+.L_divide_l1:
+	mov	r2, #1
+	mov	r3, #0
+
+	/*
+	 * If the highest bit of the dividend is set, we have to be
+	 * careful when shifting the divisor. Test this.
+	 */
+	movs	r1,r1
+	bpl	.L_old_code
+
+	/*
+	 * At this point, the highest bit of r1 is known to be set.
+	 * We abuse this below in the tst instructions.
+	 */
+	tst	r1, r0 /*, lsl #0 */
+	bmi	.L_divide_b1
+	tst	r1, r0, lsl #1
+	bmi	.L_divide_b2
+	tst	r1, r0, lsl #2
+	bmi	.L_divide_b3
+	tst	r1, r0, lsl #3
+	bmi	.L_divide_b4
+	tst	r1, r0, lsl #4
+	bmi	.L_divide_b5
+	tst	r1, r0, lsl #5
+	bmi	.L_divide_b6
+	tst	r1, r0, lsl #6
+	bmi	.L_divide_b7
+	tst	r1, r0, lsl #7
+	bmi	.L_divide_b8
+	tst	r1, r0, lsl #8
+	bmi	.L_divide_b9
+	tst	r1, r0, lsl #9
+	bmi	.L_divide_b10
+	tst	r1, r0, lsl #10
+	bmi	.L_divide_b11
+	tst	r1, r0, lsl #11
+	bmi	.L_divide_b12
+	tst	r1, r0, lsl #12
+	bmi	.L_divide_b13
+	tst	r1, r0, lsl #13
+	bmi	.L_divide_b14
+	tst	r1, r0, lsl #14
+	bmi	.L_divide_b15
+	tst	r1, r0, lsl #15
+	bmi	.L_divide_b16
+	tst	r1, r0, lsl #16
+	bmi	.L_divide_b17
+	tst	r1, r0, lsl #17
+	bmi	.L_divide_b18
+	tst	r1, r0, lsl #18
+	bmi	.L_divide_b19
+	tst	r1, r0, lsl #19
+	bmi	.L_divide_b20
+	tst	r1, r0, lsl #20
+	bmi	.L_divide_b21
+	tst	r1, r0, lsl #21
+	bmi	.L_divide_b22
+	tst	r1, r0, lsl #22
+	bmi	.L_divide_b23
+	tst	r1, r0, lsl #23
+	bmi	.L_divide_b24
+	tst	r1, r0, lsl #24
+	bmi	.L_divide_b25
+	tst	r1, r0, lsl #25
+	bmi	.L_divide_b26
+	tst	r1, r0, lsl #26
+	bmi	.L_divide_b27
+	tst	r1, r0, lsl #27
+	bmi	.L_divide_b28
+	tst	r1, r0, lsl #28
+	bmi	.L_divide_b29
+	tst	r1, r0, lsl #29
+	bmi	.L_divide_b30
+	tst	r1, r0, lsl #30
+	bmi	.L_divide_b31
+/*
+ * instead of:
+ *	tst	r1, r0, lsl #31
+ *	bmi	.L_divide_b32
+ */
+	b	.L_divide_b32
+
+.L_old_code:
+	cmp	r1, r0
+	bcc	.L_divide_b0
+	cmp	r1, r0, lsl #1
+	bcc	.L_divide_b1
+	cmp	r1, r0, lsl #2
+	bcc	.L_divide_b2
+	cmp	r1, r0, lsl #3
+	bcc	.L_divide_b3
+	cmp	r1, r0, lsl #4
+	bcc	.L_divide_b4
+	cmp	r1, r0, lsl #5
+	bcc	.L_divide_b5
+	cmp	r1, r0, lsl #6
+	bcc	.L_divide_b6
+	cmp	r1, r0, lsl #7
+	bcc	.L_divide_b7
+	cmp	r1, r0, lsl #8
+	bcc	.L_divide_b8
+	cmp	r1, r0, lsl #9
+	bcc	.L_divide_b9
+	cmp	r1, r0, lsl #10
+	bcc	.L_divide_b10
+	cmp	r1, r0, lsl #11
+	bcc	.L_divide_b11
+	cmp	r1, r0, lsl #12
+	bcc	.L_divide_b12
+	cmp	r1, r0, lsl #13
+	bcc	.L_divide_b13
+	cmp	r1, r0, lsl #14
+	bcc	.L_divide_b14
+	cmp	r1, r0, lsl #15
+	bcc	.L_divide_b15
+	cmp	r1, r0, lsl #16
+	bcc	.L_divide_b16
+	cmp	r1, r0, lsl #17
+	bcc	.L_divide_b17
+	cmp	r1, r0, lsl #18
+	bcc	.L_divide_b18
+	cmp	r1, r0, lsl #19
+	bcc	.L_divide_b19
+	cmp	r1, r0, lsl #20
+	bcc	.L_divide_b20
+	cmp	r1, r0, lsl #21
+	bcc	.L_divide_b21
+	cmp	r1, r0, lsl #22
+	bcc	.L_divide_b22
+	cmp	r1, r0, lsl #23
+	bcc	.L_divide_b23
+	cmp	r1, r0, lsl #24
+	bcc	.L_divide_b24
+	cmp	r1, r0, lsl #25
+	bcc	.L_divide_b25
+	cmp	r1, r0, lsl #26
+	bcc	.L_divide_b26
+	cmp	r1, r0, lsl #27
+	bcc	.L_divide_b27
+	cmp	r1, r0, lsl #28
+	bcc	.L_divide_b28
+	cmp	r1, r0, lsl #29
+	bcc	.L_divide_b29
+	cmp	r1, r0, lsl #30
+	bcc	.L_divide_b30
+.L_divide_b32:
+	cmp	r1, r0, lsl #31
+	subhs	r1, r1,r0, lsl #31
+	addhs	r3, r3,r2, lsl #31
+.L_divide_b31:
+	cmp	r1, r0, lsl #30
+	subhs	r1, r1,r0, lsl #30
+	addhs	r3, r3,r2, lsl #30
+.L_divide_b30:
+	cmp	r1, r0, lsl #29
+	subhs	r1, r1,r0, lsl #29
+	addhs	r3, r3,r2, lsl #29
+.L_divide_b29:
+	cmp	r1, r0, lsl #28
+	subhs	r1, r1,r0, lsl #28
+	addhs	r3, r3,r2, lsl #28
+.L_divide_b28:
+	cmp	r1, r0, lsl #27
+	subhs	r1, r1,r0, lsl #27
+	addhs	r3, r3,r2, lsl #27
+.L_divide_b27:
+	cmp	r1, r0, lsl #26
+	subhs	r1, r1,r0, lsl #26
+	addhs	r3, r3,r2, lsl #26
+.L_divide_b26:
+	cmp	r1, r0, lsl #25
+	subhs	r1, r1,r0, lsl #25
+	addhs	r3, r3,r2, lsl #25
+.L_divide_b25:
+	cmp	r1, r0, lsl #24
+	subhs	r1, r1,r0, lsl #24
+	addhs	r3, r3,r2, lsl #24
+.L_divide_b24:
+	cmp	r1, r0, lsl #23
+	subhs	r1, r1,r0, lsl #23
+	addhs	r3, r3,r2, lsl #23
+.L_divide_b23:
+	cmp	r1, r0, lsl #22
+	subhs	r1, r1,r0, lsl #22
+	addhs	r3, r3,r2, lsl #22
+.L_divide_b22:
+	cmp	r1, r0, lsl #21
+	subhs	r1, r1,r0, lsl #21
+	addhs	r3, r3,r2, lsl #21
+.L_divide_b21:
+	cmp	r1, r0, lsl #20
+	subhs	r1, r1,r0, lsl #20
+	addhs	r3, r3,r2, lsl #20
+.L_divide_b20:
+	cmp	r1, r0, lsl #19
+	subhs	r1, r1,r0, lsl #19
+	addhs	r3, r3,r2, lsl #19
+.L_divide_b19:
+	cmp	r1, r0, lsl #18
+	subhs	r1, r1,r0, lsl #18
+	addhs	r3, r3,r2, lsl #18
+.L_divide_b18:
+	cmp	r1, r0, lsl #17
+	subhs	r1, r1,r0, lsl #17
+	addhs	r3, r3,r2, lsl #17
+.L_divide_b17:
+	cmp	r1, r0, lsl #16
+	subhs	r1, r1,r0, lsl #16
+	addhs	r3, r3,r2, lsl #16
+.L_divide_b16:
+	cmp	r1, r0, lsl #15
+	subhs	r1, r1,r0, lsl #15
+	addhs	r3, r3,r2, lsl #15
+.L_divide_b15:
+	cmp	r1, r0, lsl #14
+	subhs	r1, r1,r0, lsl #14
+	addhs	r3, r3,r2, lsl #14
+.L_divide_b14:
+	cmp	r1, r0, lsl #13
+	subhs	r1, r1,r0, lsl #13
+	addhs	r3, r3,r2, lsl #13
+.L_divide_b13:
+	cmp	r1, r0, lsl #12
+	subhs	r1, r1,r0, lsl #12
+	addhs	r3, r3,r2, lsl #12
+.L_divide_b12:
+	cmp	r1, r0, lsl #11
+	subhs	r1, r1,r0, lsl #11
+	addhs	r3, r3,r2, lsl #11
+.L_divide_b11:
+	cmp	r1, r0, lsl #10
+	subhs	r1, r1,r0, lsl #10
+	addhs	r3, r3,r2, lsl #10
+.L_divide_b10:
+	cmp	r1, r0, lsl #9
+	subhs	r1, r1,r0, lsl #9
+	addhs	r3, r3,r2, lsl #9
+.L_divide_b9:
+	cmp	r1, r0, lsl #8
+	subhs	r1, r1,r0, lsl #8
+	addhs	r3, r3,r2, lsl #8
+.L_divide_b8:
+	cmp	r1, r0, lsl #7
+	subhs	r1, r1,r0, lsl #7
+	addhs	r3, r3,r2, lsl #7
+.L_divide_b7:
+	cmp	r1, r0, lsl #6
+	subhs	r1, r1,r0, lsl #6
+	addhs	r3, r3,r2, lsl #6
+.L_divide_b6:
+	cmp	r1, r0, lsl #5
+	subhs	r1, r1,r0, lsl #5
+	addhs	r3, r3,r2, lsl #5
+.L_divide_b5:
+	cmp	r1, r0, lsl #4
+	subhs	r1, r1,r0, lsl #4
+	addhs	r3, r3,r2, lsl #4
+.L_divide_b4:
+	cmp	r1, r0, lsl #3
+	subhs	r1, r1,r0, lsl #3
+	addhs	r3, r3,r2, lsl #3
+.L_divide_b3:
+	cmp	r1, r0, lsl #2
+	subhs	r1, r1,r0, lsl #2
+	addhs	r3, r3,r2, lsl #2
+.L_divide_b2:
+	cmp	r1, r0, lsl #1
+	subhs	r1, r1,r0, lsl #1
+	addhs	r3, r3,r2, lsl #1
+.L_divide_b1:
+	cmp	r1, r0
+	subhs	r1, r1, r0
+	addhs	r3, r3, r2
+.L_divide_b0:
+
+	tst	ip, #0x20000000
+	bne	.L_udivide_l1
+	mov	r0, r3
+	cmp	ip, #0
+	rsbmi	r1, r1, #0
+	movs	ip, ip, lsl #1
+	bicmi	r0, r0, #0x80000000	/* Fix incase we divided 0x80000000 */
+	rsbmi	r0, r0, #0
+	mov	pc, lr
+
+.L_udivide_l1:
+	tst	ip, #0x10000000
+	mov	r1, r1, lsl #1
+	orrne	r1, r1, #1
+	mov	r3, r3, lsl #1
+	cmp	r1, r0
+	subhs	r1, r1, r0
+	addhs	r3, r3, r2
+	mov	r0, r3
+	mov	pc, lr

+ 42 - 0
libcpu/arm/common/showmem.c

@@ -0,0 +1,42 @@
+/*
+ * File      : showmem.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-07-29     Bernard      first version from QiuYi implementation
+ */
+
+#include <rtthread.h>
+
+void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
+{
+	int i = 0, j =0;
+
+	RT_ASSERT(addr);
+
+	addr = addr & ~0xF;
+	size = 4*((size + 3)/4);
+
+	while(i < size)
+	{
+		rt_kprintf("0x%08x: ", addr );
+
+		for(j=0; j<4; j++)
+		{
+			rt_kprintf("0x%08x  ", *(rt_uint32_t *)addr);
+
+			addr += 4;
+			i++;
+		}
+
+		rt_kprintf("\n");
+	}
+
+	return;
+}

+ 178 - 0
libcpu/arm/lm3s/context_rvds.S

@@ -0,0 +1,178 @@
+;/*
+; * File      : context.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-17     Bernard      first version
+; */
+
+;/**
+; * @addtogroup STM32
+; */
+;/*@{*/
+
+NVIC_INT_CTRL   EQU     0xE000ED04               ; interrupt control state register
+NVIC_SYSPRI2    EQU     0xE000ED20               ; system priority register (2)
+NVIC_PENDSV_PRI EQU     0x00000000               ; PendSV priority value (lowest)
+NVIC_PENDSVSET  EQU     0x10000000               ; value to trigger PendSV exception
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	THUMB
+	REQUIRE8
+	PRESERVE8
+
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable    PROC
+	EXPORT  rt_hw_interrupt_disable
+	MRS		r0, PRIMASK
+	CPSID   I
+	BX		LR
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable    PROC
+	EXPORT  rt_hw_interrupt_enable
+	MSR		PRIMASK, r0
+	BX      LR
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch    PROC
+	EXPORT rt_hw_context_switch
+	LDR		r2, =rt_interrupt_from_thread
+	STR		r0, [r2]
+	
+	LDR		r2, =rt_interrupt_to_thread
+	STR		r1, [r2]
+
+    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+	STR     r1, [r0]
+	CPSIE   I                       ; enable interrupts at processor level
+	BX      LR
+	ENDP
+
+; r0 --> swith from thread stack
+; r1 --> swith to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+rt_hw_pend_sv	PROC
+	EXPORT rt_hw_pend_sv
+	LDR		r0, =rt_interrupt_from_thread
+	LDR		r1, [r0]
+	CBZ		r1, swtich_to_thread    ; skip register save at the first time
+
+	MRS     r1, psp                 ; get from thread stack pointer
+	STMFD	r1!, {r4 - r11}			; push r4 - r11 register
+	LDR		r0, [r0]
+	STR		r1, [r0]				; update from thread stack pointer
+
+swtich_to_thread
+	LDR		r1, =rt_interrupt_to_thread
+	LDR		r1, [r1]
+	LDR		r1, [r1]				; load thread stack pointer 
+
+	LDMFD	r1!, {r4 - r11}			; pop r4 - r11 register
+	MSR		psp, r1					; update stack pointer
+
+	ORR     lr, lr, #0x04
+	BX		lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to    PROC
+	EXPORT rt_hw_context_switch_to
+	LDR		r1, =rt_interrupt_to_thread
+	STR		r0, [r1]
+
+	; set from thread to 0
+	LDR		r1, =rt_interrupt_from_thread
+	MOV		r0, #0x0
+	STR		r0, [r1]
+
+	; set the PendSV exception priority
+    LDR     r0, =NVIC_SYSPRI2
+    LDR     r1, =NVIC_PENDSV_PRI
+    STR     r1, [r0]
+
+    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+
+    CPSIE   I                       ; enable interrupts at processor level
+	
+	; never reach here!
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
+; * {
+; *		if (rt_thread_switch_interrput_flag == 1)
+; * 	{
+; *			rt_interrupt_to_thread = to;
+; * 	}
+; * 	else
+; * 	{
+; *			rt_thread_switch_interrput_flag = 1;
+; * 		rt_interrupt_from_thread = from;
+; * 		rt_interrupt_to_thread = to;
+; * 	}
+; * }
+; */
+rt_hw_context_switch_interrupt    PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR 	r2, =rt_thread_switch_interrput_flag
+	LDR 	r3, [r2]
+	CMP 	r3, #1
+	BEQ 	_reswitch
+	MOV 	r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR 	r3, [r2]
+	LDR 	r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR 	r0, [r2]
+_reswitch
+	LDR 	r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR 	r1, [r2]
+	BX		lr
+	ENDP
+
+rt_hw_interrupt_thread_switch	PROC
+	EXPORT rt_hw_interrupt_thread_switch
+	LDR		r0, =rt_thread_switch_interrput_flag
+	LDR		r1, [r0]
+	CBZ		r1, _no_switch
+
+	; clear rt_thread_switch_interrput_flag to 0
+	MOV		r1, #0x00
+	STR		r1, [r0]
+
+	; trigger context switch
+    LDR     r0, =NVIC_INT_CTRL      ; trigger the PendSV exception (causes context switch)
+    LDR     r1, =NVIC_PENDSVSET
+    STR     r1, [r0]
+
+_no_switch
+	BX		lr
+
+	ENDP
+
+	END

+ 42 - 0
libcpu/arm/lm3s/cpu.c

@@ -0,0 +1,42 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ */
+
+#include <rtthread.h>
+
+/**
+ * @addtogroup S3C2410
+ */
+/*@{*/
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+	/*NOTREACHED*/
+}
+
+/**
+ *  shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	RT_ASSERT(0);
+}
+
+/*@}*/

+ 25 - 0
libcpu/arm/lm3s/interrupt.c

@@ -0,0 +1,25 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-13     Bernard      first version
+ */
+
+#include <rtthread.h>
+
+#define MAX_HANDLERS	32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/*@}*/

+ 42 - 0
libcpu/arm/lm3s/kservice.c

@@ -0,0 +1,42 @@
+#include <rtthread.h>
+
+#include <stdio.h>
+#include <string.h>
+
+/* 
+ * Only need when RealView MDK is used.
+ */
+void *rt_memset(void * s, int c, rt_ubase_t count)
+{
+	return memset(s, c, count);
+}
+
+void *rt_memcpy(void * dst, const void *src, rt_ubase_t count)
+{
+	return memcpy(dst, src, count);
+}
+
+rt_ubase_t rt_strncmp(const char * cs, const char * ct, rt_ubase_t count)
+{
+	return strncmp(cs, ct, count);
+}
+
+/**
+ * This function will show the version of rt-thread rtos
+ */
+void rt_show_version()
+{
+	rt_kprintf(" \\ | /\n");
+	rt_kprintf("- RT - Thread Operating System\n");
+	rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);
+	rt_kprintf(" 2006 - 2009 Copyright by rt-thread team\n");
+}
+
+void rt_kprintf(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vprintf(fmt, args);
+	va_end(args);
+}

+ 362 - 0
libcpu/arm/lm3s/serial.c

@@ -0,0 +1,362 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-06-11     Bernard      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <inc/hw_types.h>
+#include <inc/hw_memmap.h>
+#include <inc/hw_uart.h>
+#include <inc/hw_ints.h>
+#include <driverlib/gpio.h>
+#include <driverlib/sysctl.h>
+#include <driverlib/interrupt.h>
+
+#include <uart.h>
+#include "board.h"
+
+extern void rt_hw_interrupt_thread_switch(void);
+
+#define RT_UART_RX_BUFFER_SIZE 64
+
+/* LM3S serial device */
+struct rt_lm3s_serial
+{
+	/* inherit from device */
+	struct rt_device parent;
+
+	rt_uint32_t hw_base;
+	rt_uint32_t baudrate;
+
+	/* reception field */
+	rt_uint16_t save_index, read_index;
+	rt_uint8_t  rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+
+#ifdef RT_USING_UART1
+struct rt_lm3s_serial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_lm3s_serial serial2;
+#endif
+
+void rt_hw_serial_init(void);
+
+void rt_hw_uart_isr(struct rt_lm3s_serial* serial)
+{
+    rt_device_t device;
+    rt_uint32_t status;
+
+    device = (struct rt_device*)serial;
+    UARTIntStatus(serial->hw_base, true);
+
+    /* clear interrupt status */
+    UARTIntClear(serial->hw_base, status);
+
+    if (device->flag & RT_DEVICE_FLAG_INT_RX)
+    {
+        char ch;
+		rt_base_t level;
+
+        while (UARTCharsAvail(serial->hw_base))
+        {
+            ch = UARTCharGetNonBlocking(serial->hw_base);
+
+            /* disable interrupt */
+			level = rt_hw_interrupt_disable();
+
+			/* read character */
+			serial->rx_buffer[serial->save_index] = ch;
+			serial->save_index ++;
+			if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+				serial->save_index = 0;
+
+			/* if the next position is read index, discard this 'read char' */
+			if (serial->save_index == serial->read_index)
+			{
+				serial->read_index ++;
+				if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					serial->read_index = 0;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+        }
+
+		/* invoke callback */
+		if(device->rx_indicate != RT_NULL)
+		{
+		    rt_int32_t length;
+
+		    length = serial->save_index - serial->read_index;
+		    if (length < 0) length += RT_UART_RX_BUFFER_SIZE;
+            device->rx_indicate(device, length);
+		}
+    }
+}
+
+#ifdef RT_USING_UART1
+void rt_hw_uart_isr_1(int irqno)
+{
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	/* get serial device */
+	rt_hw_uart_isr(&serial1);
+
+	/* leave interrupt */
+	rt_interrupt_leave();
+	rt_hw_interrupt_thread_switch();
+}
+#endif
+
+#ifdef RT_USING_UART2
+void rt_hw_uart_isr_2(int irqno)
+{
+	/* enter interrupt */
+	rt_interrupt_enter();
+
+	/* get serial device */
+	rt_hw_uart_isr(&serial2);
+
+	/* leave interrupt */
+	rt_interrupt_leave();
+	rt_hw_interrupt_thread_switch();
+}
+#endif
+
+/**
+ * @addtogroup LM3S
+ */
+/*@{*/
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_lm3s_serial* serial;
+	serial = (struct rt_lm3s_serial*) dev;
+
+	RT_ASSERT(serial != RT_NULL);
+
+    if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+    {
+        /* enable interrupt */
+        if (serial->hw_base == UART0_BASE)
+            IntEnable(INT_UART0);
+        else if (serial->hw_base == UART1_BASE)
+            IntEnable(INT_UART1);
+
+        UARTIntEnable(serial->hw_base, UART_INT_RX | UART_INT_RT);
+    }
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	struct rt_lm3s_serial* serial;
+	serial = (struct rt_lm3s_serial*) dev;
+
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* disable UART rx interrupt */
+		UARTIntDisable(serial->hw_base, UART_INT_RX | UART_INT_RT);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_lm3s_serial *serial = (struct rt_lm3s_serial*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (serial->read_index != serial->save_index)
+			{
+				*ptr = serial->rx_buffer[serial->read_index];
+
+				serial->read_index ++;
+				if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					serial->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++; size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+	{
+		/* not support right now */
+		RT_ASSERT(0);
+	}
+
+	/* polling mode */
+	while (size)
+	{
+	    *ptr = UARTCharGetNonBlocking(serial->hw_base);
+
+	    ptr ++; size --;
+	}
+
+	return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	struct rt_lm3s_serial* serial;
+	char *ptr;
+
+	serial = (struct rt_lm3s_serial*) dev;
+	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+	{
+		/* not support */
+		RT_ASSERT(0);
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+	{
+		/* not support */
+		RT_ASSERT(0);
+	}
+
+	/* polling write */
+	ptr = (char *)buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_STREAM)
+	{
+		/* stream mode */
+		while (size)
+		{
+			if (*ptr == '\n')
+				while (UARTCharPutNonBlocking(serial->hw_base, '\r') == false);
+
+			while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
+
+			ptr ++;
+			size --;
+		}
+	}
+	else
+	{
+		while (size)
+		{
+			while (UARTCharPutNonBlocking(serial->hw_base, *ptr) == false);
+
+			ptr ++;
+			size --;
+		}
+	}
+
+	return (rt_size_t) ptr - (rt_size_t) buffer;
+}
+
+void rt_hw_serial_init(void)
+{
+	struct rt_lm3s_serial* serial;
+
+#ifdef RT_USING_UART1
+	serial = &serial1;
+
+	serial->parent.type = RT_Device_Class_Char;
+
+	serial->hw_base = UART0_BASE;
+	serial->baudrate = 115200;
+
+	rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
+	serial->read_index = serial->save_index = 0;
+
+	/* enable UART0 clock */
+    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
+    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
+
+	/* set UART0 pinmux */
+    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
+
+	/* Configure the UART for 115,200, 8-N-1 operation. */
+	UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), serial->baudrate,
+                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
+                         UART_CONFIG_PAR_NONE));
+
+	serial->parent.init 	= rt_serial_init;
+	serial->parent.open 	= rt_serial_open;
+	serial->parent.close    = rt_serial_close;
+	serial->parent.read 	= rt_serial_read;
+	serial->parent.write    = rt_serial_write;
+	serial->parent.control  = rt_serial_control;
+	serial->parent.private  = RT_NULL;
+
+	rt_device_register(&serial->parent,
+		"uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+	serial = &serial2;
+
+	serial->parent.type = RT_Device_Class_Char;
+
+	serial->hw_base = 0xE0010000;
+	serial->baudrate = 115200;
+
+	rt_memset(serial->rx_buffer, 0, sizeof(serial->rx_buffer));
+	serial->read_index = serial->save_index = 0;
+
+	serial->parent.init 	= rt_serial_init;
+	serial->parent.open 	= rt_serial_open;
+	serial->parent.close    = rt_serial_close;
+	serial->parent.read 	= rt_serial_read;
+	serial->parent.write    = rt_serial_write;
+	serial->parent.control  = rt_serial_control;
+	serial->parent.private  = RT_NULL;
+
+	rt_device_register(&serial->parent,
+		"uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+}
+
+/*@}*/

+ 59 - 0
libcpu/arm/lm3s/stack.c

@@ -0,0 +1,59 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      the first version
+ */
+#include <rtthread.h>
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk)   = 0x01000000L;					/* PSR */
+	*(--stk) = (unsigned long)tentry;		/* entry point, pc */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 251 - 0
libcpu/arm/lm3s/start_rvds.S

@@ -0,0 +1,251 @@
+; <<< Use Configuration Wizard in Context Menu >>>
+;******************************************************************************
+;
+; Startup.s - Startup code for Stellaris.
+;
+; Copyright (c) 2006-2008 Luminary Micro, Inc.  All rights reserved.
+; 
+; Software License Agreement
+; 
+; Luminary Micro, Inc. (LMI) is supplying this software for use solely and
+; exclusively on LMI's microcontroller products.
+; 
+; The software is owned by LMI and/or its suppliers, and is protected under
+; applicable copyright laws.  All rights are reserved.  You may not combine
+; this software with "viral" open-source software in order to form a larger
+; program.  Any use in violation of the foregoing restrictions may subject
+; the user to criminal sanctions under applicable laws, as well as to civil
+; liability for the breach of the terms and conditions of this license.
+; 
+; THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+; OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+; LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+; CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+; 
+; This is part of revision 2523 of the Stellaris Peripheral Driver Library.
+;
+;******************************************************************************
+
+;******************************************************************************
+;
+; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+;******************************************************************************
+Stack   EQU     0x00000100
+
+;******************************************************************************
+;
+; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+;
+;******************************************************************************
+Heap    EQU     0x00000000
+
+;******************************************************************************
+;
+; Allocate space for the stack.
+;
+;******************************************************************************
+        AREA    STACK, NOINIT, READWRITE, ALIGN=3
+StackMem
+        SPACE   Stack
+__initial_sp
+
+;******************************************************************************
+;
+; Allocate space for the heap.
+;
+;******************************************************************************
+        AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+HeapMem
+        SPACE   Heap
+__heap_limit
+
+		IMPORT rt_hw_pend_sv
+		IMPORT rt_hw_timer_handler
+		IMPORT rt_hw_uart_isr_1
+
+;******************************************************************************
+;
+; Indicate that the code in this file preserves 8-byte alignment of the stack.
+;
+;******************************************************************************
+        PRESERVE8
+
+;******************************************************************************
+;
+; Place code into the reset code section.
+;
+;******************************************************************************
+        AREA    RESET, CODE, READONLY
+        THUMB
+
+;******************************************************************************
+;
+; The vector table.
+;
+;******************************************************************************
+        EXPORT  __Vectors
+__Vectors
+        DCD     StackMem + Stack            ; Top of Stack
+        DCD     Reset_Handler               ; Reset Handler
+        DCD     NmiSR                       ; NMI Handler
+        DCD     FaultISR                    ; Hard Fault Handler
+        DCD     IntDefaultHandler           ; MPU Fault Handler
+        DCD     IntDefaultHandler           ; Bus Fault Handler
+        DCD     IntDefaultHandler           ; Usage Fault Handler
+        DCD     0                           ; Reserved
+        DCD     0                           ; Reserved
+        DCD     0                           ; Reserved
+        DCD     0                           ; Reserved
+        DCD     IntDefaultHandler           ; SVCall Handler
+        DCD     IntDefaultHandler           ; Debug Monitor Handler
+        DCD     0                           ; Reserved
+        DCD     rt_hw_pend_sv           	; PendSV Handler
+        DCD     rt_hw_timer_handler         ; SysTick Handler
+        DCD     IntDefaultHandler           ; GPIO Port A
+        DCD     IntDefaultHandler           ; GPIO Port B
+        DCD     IntDefaultHandler           ; GPIO Port C
+        DCD     IntDefaultHandler           ; GPIO Port D
+        DCD     IntDefaultHandler           ; GPIO Port E
+        DCD     rt_hw_uart_isr_1           	; UART0
+        DCD     IntDefaultHandler           ; UART1
+        DCD     IntDefaultHandler           ; SSI
+        DCD     IntDefaultHandler           ; I2C
+        DCD     IntDefaultHandler           ; PWM Fault
+        DCD     IntDefaultHandler           ; PWM Generator 0
+        DCD     IntDefaultHandler           ; PWM Generator 1
+        DCD     IntDefaultHandler           ; PWM Generator 2
+        DCD     IntDefaultHandler           ; Quadrature Encoder
+        DCD     IntDefaultHandler           ; ADC Sequence 0
+        DCD     IntDefaultHandler           ; ADC Sequence 1
+        DCD     IntDefaultHandler           ; ADC Sequence 2
+        DCD     IntDefaultHandler           ; ADC Sequence 3
+        DCD     IntDefaultHandler           ; Watchdog
+        DCD     IntDefaultHandler           ; Timer 0A
+        DCD     IntDefaultHandler           ; Timer 0B
+        DCD     IntDefaultHandler           ; Timer 1A
+        DCD     IntDefaultHandler           ; Timer 1B
+        DCD     IntDefaultHandler           ; Timer 2A
+        DCD     IntDefaultHandler           ; Timer 2B
+        DCD     IntDefaultHandler           ; Comp 0
+        DCD     IntDefaultHandler           ; Comp 1
+        DCD     IntDefaultHandler           ; Comp 2
+        DCD     IntDefaultHandler           ; System Control
+        DCD     IntDefaultHandler           ; Flash Control
+        DCD     IntDefaultHandler           ; GPIO Port F
+        DCD     IntDefaultHandler           ; GPIO Port G
+        DCD     IntDefaultHandler           ; GPIO Port H
+        DCD     IntDefaultHandler           ; UART2 Rx and Tx
+        DCD     IntDefaultHandler           ; SSI1 Rx and Tx
+        DCD     IntDefaultHandler           ; Timer 3 subtimer A
+        DCD     IntDefaultHandler           ; Timer 3 subtimer B
+        DCD     IntDefaultHandler           ; I2C1 Master and Slave
+        DCD     IntDefaultHandler           ; Quadrature Encoder 1
+        DCD     IntDefaultHandler           ; CAN0
+        DCD     IntDefaultHandler           ; CAN1
+        DCD     IntDefaultHandler           ; CAN2
+        DCD     IntDefaultHandler           ; Ethernet
+        DCD     IntDefaultHandler           ; Hibernate
+        DCD     IntDefaultHandler           ; USB0
+        DCD     IntDefaultHandler           ; PWM Generator 3
+        DCD     IntDefaultHandler           ; uDMA Software Transfer
+        DCD     IntDefaultHandler           ; uDMA Error
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor first starts execution
+; following a reset event.
+;
+;******************************************************************************
+        EXPORT  Reset_Handler
+Reset_Handler
+        ;
+        ; Call the C library enty point that handles startup.  This will copy
+        ; the .data section initializers from flash to SRAM and zero fill the
+        ; .bss section.
+        ;
+        IMPORT  __main
+        B       __main
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives a NMI.  This
+; simply enters an infinite loop, preserving the system state for examination
+; by a debugger.
+;
+;******************************************************************************
+NmiSR
+        B       NmiSR
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives a fault
+; interrupt.  This simply enters an infinite loop, preserving the system state
+; for examination by a debugger.
+;
+;******************************************************************************
+FaultISR
+        B       FaultISR
+
+;******************************************************************************
+;
+; This is the code that gets called when the processor receives an unexpected
+; interrupt.  This simply enters an infinite loop, preserving the system state
+; for examination by a debugger.
+;
+;******************************************************************************
+IntDefaultHandler
+        B       IntDefaultHandler
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+        ALIGN
+
+;******************************************************************************
+;
+; Some code in the normal code section for initializing the heap and stack.
+;
+;******************************************************************************
+        AREA    |.text|, CODE, READONLY
+
+;******************************************************************************
+;
+; The function expected of the C library startup code for defining the stack
+; and heap memory locations.  For the C library version of the startup code,
+; provide this function so that the C library initialization code can find out
+; the location of the stack and heap.
+;
+;******************************************************************************
+    IF :DEF: __MICROLIB
+        EXPORT  __initial_sp
+        EXPORT  __heap_base
+        EXPORT __heap_limit
+    ELSE
+        IMPORT  __use_two_region_memory
+        EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+        LDR     R0, =HeapMem
+        LDR     R1, =(StackMem + Stack)
+        LDR     R2, =(HeapMem + Heap)
+        LDR     R3, =StackMem
+        BX      LR
+    ENDIF
+
+;******************************************************************************
+;
+; Make sure the end of this section is aligned.
+;
+;******************************************************************************
+        ALIGN
+
+;******************************************************************************
+;
+; Tell the assembler that we're done.
+;
+;******************************************************************************
+        END

+ 393 - 0
libcpu/arm/lpc214x/LPC214x.h

@@ -0,0 +1,393 @@
+/***********************************************************************/
+/*  This file is part of the uVision/ARM development tools             */
+/*  Copyright KEIL ELEKTRONIK GmbH 2002-2005                           */
+/***********************************************************************/
+/*                                                                     */
+/*  LPC214X.H:  Header file for Philips LPC2141/42/44/46/48            */
+/*                                                                     */
+/***********************************************************************/
+
+#ifndef __LPC214x_H
+#define __LPC214x_H
+
+/* Vectored Interrupt Controller (VIC) */
+#define VICIRQStatus    (*((volatile unsigned long *) 0xFFFFF000))
+#define VICFIQStatus    (*((volatile unsigned long *) 0xFFFFF004))
+#define VICRawIntr      (*((volatile unsigned long *) 0xFFFFF008))
+#define VICIntSelect    (*((volatile unsigned long *) 0xFFFFF00C))
+#define VICIntEnable    (*((volatile unsigned long *) 0xFFFFF010))
+#define VICIntEnClr     (*((volatile unsigned long *) 0xFFFFF014))
+#define VICSoftInt      (*((volatile unsigned long *) 0xFFFFF018))
+#define VICSoftIntClr   (*((volatile unsigned long *) 0xFFFFF01C))
+#define VICProtection   (*((volatile unsigned long *) 0xFFFFF020))
+#define VICVectAddr     (*((volatile unsigned long *) 0xFFFFF030))
+#define VICDefVectAddr  (*((volatile unsigned long *) 0xFFFFF034))
+#define VICVectAddr0    (*((volatile unsigned long *) 0xFFFFF100))
+#define VICVectAddr1    (*((volatile unsigned long *) 0xFFFFF104))
+#define VICVectAddr2    (*((volatile unsigned long *) 0xFFFFF108))
+#define VICVectAddr3    (*((volatile unsigned long *) 0xFFFFF10C))
+#define VICVectAddr4    (*((volatile unsigned long *) 0xFFFFF110))
+#define VICVectAddr5    (*((volatile unsigned long *) 0xFFFFF114))
+#define VICVectAddr6    (*((volatile unsigned long *) 0xFFFFF118))
+#define VICVectAddr7    (*((volatile unsigned long *) 0xFFFFF11C))
+#define VICVectAddr8    (*((volatile unsigned long *) 0xFFFFF120))
+#define VICVectAddr9    (*((volatile unsigned long *) 0xFFFFF124))
+#define VICVectAddr10   (*((volatile unsigned long *) 0xFFFFF128))
+#define VICVectAddr11   (*((volatile unsigned long *) 0xFFFFF12C))
+#define VICVectAddr12   (*((volatile unsigned long *) 0xFFFFF130))
+#define VICVectAddr13   (*((volatile unsigned long *) 0xFFFFF134))
+#define VICVectAddr14   (*((volatile unsigned long *) 0xFFFFF138))
+#define VICVectAddr15   (*((volatile unsigned long *) 0xFFFFF13C))
+#define VICVectCntl0    (*((volatile unsigned long *) 0xFFFFF200))
+#define VICVectCntl1    (*((volatile unsigned long *) 0xFFFFF204))
+#define VICVectCntl2    (*((volatile unsigned long *) 0xFFFFF208))
+#define VICVectCntl3    (*((volatile unsigned long *) 0xFFFFF20C))
+#define VICVectCntl4    (*((volatile unsigned long *) 0xFFFFF210))
+#define VICVectCntl5    (*((volatile unsigned long *) 0xFFFFF214))
+#define VICVectCntl6    (*((volatile unsigned long *) 0xFFFFF218))
+#define VICVectCntl7    (*((volatile unsigned long *) 0xFFFFF21C))
+#define VICVectCntl8    (*((volatile unsigned long *) 0xFFFFF220))
+#define VICVectCntl9    (*((volatile unsigned long *) 0xFFFFF224))
+#define VICVectCntl10   (*((volatile unsigned long *) 0xFFFFF228))
+#define VICVectCntl11   (*((volatile unsigned long *) 0xFFFFF22C))
+#define VICVectCntl12   (*((volatile unsigned long *) 0xFFFFF230))
+#define VICVectCntl13   (*((volatile unsigned long *) 0xFFFFF234))
+#define VICVectCntl14   (*((volatile unsigned long *) 0xFFFFF238))
+#define VICVectCntl15   (*((volatile unsigned long *) 0xFFFFF23C))
+
+/* Pin Connect Block */
+#define PINSEL0         (*((volatile unsigned long *) 0xE002C000))
+#define PINSEL1         (*((volatile unsigned long *) 0xE002C004))
+#define PINSEL2         (*((volatile unsigned long *) 0xE002C014))
+
+/* General Purpose Input/Output (GPIO) */
+#define IOPIN0          (*((volatile unsigned long *) 0xE0028000))
+#define IOSET0          (*((volatile unsigned long *) 0xE0028004))
+#define IODIR0          (*((volatile unsigned long *) 0xE0028008))
+#define IOCLR0          (*((volatile unsigned long *) 0xE002800C))
+#define IOPIN1          (*((volatile unsigned long *) 0xE0028010))
+#define IOSET1          (*((volatile unsigned long *) 0xE0028014))
+#define IODIR1          (*((volatile unsigned long *) 0xE0028018))
+#define IOCLR1          (*((volatile unsigned long *) 0xE002801C))
+#define IO0PIN          (*((volatile unsigned long *) 0xE0028000))
+#define IO0SET          (*((volatile unsigned long *) 0xE0028004))
+#define IO0DIR          (*((volatile unsigned long *) 0xE0028008))
+#define IO0CLR          (*((volatile unsigned long *) 0xE002800C))
+#define IO1PIN          (*((volatile unsigned long *) 0xE0028010))
+#define IO1SET          (*((volatile unsigned long *) 0xE0028014))
+#define IO1DIR          (*((volatile unsigned long *) 0xE0028018))
+#define IO1CLR          (*((volatile unsigned long *) 0xE002801C))
+#define FIO0DIR         (*((volatile unsigned long *) 0x3FFFC000))
+#define FIO0MASK        (*((volatile unsigned long *) 0x3FFFC010))
+#define FIO0PIN         (*((volatile unsigned long *) 0x3FFFC014))
+#define FIO0SET         (*((volatile unsigned long *) 0x3FFFC018))
+#define FIO0CLR         (*((volatile unsigned long *) 0x3FFFC01C))
+#define FIO1DIR         (*((volatile unsigned long *) 0x3FFFC020))
+#define FIO1MASK        (*((volatile unsigned long *) 0x3FFFC030))
+#define FIO1PIN         (*((volatile unsigned long *) 0x3FFFC034))
+#define FIO1SET         (*((volatile unsigned long *) 0x3FFFC038))
+#define FIO1CLR         (*((volatile unsigned long *) 0x3FFFC03C))
+
+/* Memory Accelerator Module (MAM) */
+#define MAMCR           (*((volatile unsigned char *) 0xE01FC000))
+#define MAMTIM          (*((volatile unsigned char *) 0xE01FC004))
+#define MEMMAP          (*((volatile unsigned char *) 0xE01FC040))
+
+/* Phase Locked Loop 0 (PLL0) */
+#define PLL0CON         (*((volatile unsigned char *) 0xE01FC080))
+#define PLL0CFG         (*((volatile unsigned char *) 0xE01FC084))
+#define PLL0STAT        (*((volatile unsigned short*) 0xE01FC088))
+#define PLL0FEED        (*((volatile unsigned char *) 0xE01FC08C))
+
+/* Phase Locked Loop 1 (PLL1) */
+#define PLL1CON         (*((volatile unsigned char *) 0xE01FC0A0))
+#define PLL1CFG         (*((volatile unsigned char *) 0xE01FC0A4))
+#define PLL1STAT        (*((volatile unsigned short*) 0xE01FC0A8))
+#define PLL1FEED        (*((volatile unsigned char *) 0xE01FC0AC))
+
+/* VPB Divider */
+#define VPBDIV          (*((volatile unsigned char *) 0xE01FC100))
+
+/* Power Control */
+#define PCON            (*((volatile unsigned char *) 0xE01FC0C0))
+#define PCONP           (*((volatile unsigned long *) 0xE01FC0C4))
+
+/* External Interrupts */
+#define EXTINT          (*((volatile unsigned char *) 0xE01FC140))
+#define INTWAKE         (*((volatile unsigned short*) 0xE01FC144))
+#define EXTMODE         (*((volatile unsigned char *) 0xE01FC148))
+#define EXTPOLAR        (*((volatile unsigned char *) 0xE01FC14C))
+
+/* Reset */
+#define RSID            (*((volatile unsigned char *) 0xE01FC180))
+
+/* Code Security / Debugging */
+#define CSPR            (*((volatile unsigned char *) 0xE01FC184))
+
+/* System Control Miscellaneous */
+#define SCS             (*((volatile unsigned long *) 0xE01FC1A0))
+
+/* Timer 0 */
+#define T0IR            (*((volatile unsigned long *) 0xE0004000))
+#define T0TCR           (*((volatile unsigned long *) 0xE0004004))
+#define T0TC            (*((volatile unsigned long *) 0xE0004008))
+#define T0PR            (*((volatile unsigned long *) 0xE000400C))
+#define T0PC            (*((volatile unsigned long *) 0xE0004010))
+#define T0MCR           (*((volatile unsigned long *) 0xE0004014))
+#define T0MR0           (*((volatile unsigned long *) 0xE0004018))
+#define T0MR1           (*((volatile unsigned long *) 0xE000401C))
+#define T0MR2           (*((volatile unsigned long *) 0xE0004020))
+#define T0MR3           (*((volatile unsigned long *) 0xE0004024))
+#define T0CCR           (*((volatile unsigned long *) 0xE0004028))
+#define T0CR0           (*((volatile unsigned long *) 0xE000402C))
+#define T0CR1           (*((volatile unsigned long *) 0xE0004030))
+#define T0CR2           (*((volatile unsigned long *) 0xE0004034))
+#define T0CR3           (*((volatile unsigned long *) 0xE0004038))
+#define T0EMR           (*((volatile unsigned long *) 0xE000403C))
+#define T0CTCR          (*((volatile unsigned long *) 0xE0004070))
+
+/* Timer 1 */
+#define T1IR            (*((volatile unsigned long *) 0xE0008000))
+#define T1TCR           (*((volatile unsigned long *) 0xE0008004))
+#define T1TC            (*((volatile unsigned long *) 0xE0008008))
+#define T1PR            (*((volatile unsigned long *) 0xE000800C))
+#define T1PC            (*((volatile unsigned long *) 0xE0008010))
+#define T1MCR           (*((volatile unsigned long *) 0xE0008014))
+#define T1MR0           (*((volatile unsigned long *) 0xE0008018))
+#define T1MR1           (*((volatile unsigned long *) 0xE000801C))
+#define T1MR2           (*((volatile unsigned long *) 0xE0008020))
+#define T1MR3           (*((volatile unsigned long *) 0xE0008024))
+#define T1CCR           (*((volatile unsigned long *) 0xE0008028))
+#define T1CR0           (*((volatile unsigned long *) 0xE000802C))
+#define T1CR1           (*((volatile unsigned long *) 0xE0008030))
+#define T1CR2           (*((volatile unsigned long *) 0xE0008034))
+#define T1CR3           (*((volatile unsigned long *) 0xE0008038))
+#define T1EMR           (*((volatile unsigned long *) 0xE000803C))
+#define T1CTCR          (*((volatile unsigned long *) 0xE0008070))
+
+/* Pulse Width Modulator (PWM) */
+#define PWMIR           (*((volatile unsigned long *) 0xE0014000))
+#define PWMTCR          (*((volatile unsigned long *) 0xE0014004))
+#define PWMTC           (*((volatile unsigned long *) 0xE0014008))
+#define PWMPR           (*((volatile unsigned long *) 0xE001400C))
+#define PWMPC           (*((volatile unsigned long *) 0xE0014010))
+#define PWMMCR          (*((volatile unsigned long *) 0xE0014014))
+#define PWMMR0          (*((volatile unsigned long *) 0xE0014018))
+#define PWMMR1          (*((volatile unsigned long *) 0xE001401C))
+#define PWMMR2          (*((volatile unsigned long *) 0xE0014020))
+#define PWMMR3          (*((volatile unsigned long *) 0xE0014024))
+#define PWMMR4          (*((volatile unsigned long *) 0xE0014040))
+#define PWMMR5          (*((volatile unsigned long *) 0xE0014044))
+#define PWMMR6          (*((volatile unsigned long *) 0xE0014048))
+#define PWMPCR          (*((volatile unsigned long *) 0xE001404C))
+#define PWMLER          (*((volatile unsigned long *) 0xE0014050))
+
+/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
+#define U0RBR           (*((volatile unsigned char *) 0xE000C000))
+#define U0THR           (*((volatile unsigned char *) 0xE000C000))
+#define U0IER           (*((volatile unsigned long *) 0xE000C004))
+#define U0IIR           (*((volatile unsigned long *) 0xE000C008))
+#define U0FCR           (*((volatile unsigned char *) 0xE000C008))
+#define U0LCR           (*((volatile unsigned char *) 0xE000C00C))
+#define U0MCR           (*((volatile unsigned char *) 0xE000C010))
+#define U0LSR           (*((volatile unsigned char *) 0xE000C014))
+#define U0MSR           (*((volatile unsigned char *) 0xE000C018))
+#define U0SCR           (*((volatile unsigned char *) 0xE000C01C))
+#define U0DLL           (*((volatile unsigned char *) 0xE000C000))
+#define U0DLM           (*((volatile unsigned char *) 0xE000C004))
+#define U0ACR           (*((volatile unsigned long *) 0xE000C020))
+#define U0FDR           (*((volatile unsigned long *) 0xE000C028))
+#define U0TER           (*((volatile unsigned char *) 0xE000C030))
+
+/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
+#define U1RBR           (*((volatile unsigned char *) 0xE0010000))
+#define U1THR           (*((volatile unsigned char *) 0xE0010000))
+#define U1IER           (*((volatile unsigned long *) 0xE0010004))
+#define U1IIR           (*((volatile unsigned long *) 0xE0010008))
+#define U1FCR           (*((volatile unsigned char *) 0xE0010008))
+#define U1LCR           (*((volatile unsigned char *) 0xE001000C))
+#define U1MCR           (*((volatile unsigned char *) 0xE0010010))
+#define U1LSR           (*((volatile unsigned char *) 0xE0010014))
+#define U1MSR           (*((volatile unsigned char *) 0xE0010018))
+#define U1SCR           (*((volatile unsigned char *) 0xE001001C))
+#define U1DLL           (*((volatile unsigned char *) 0xE0010000))
+#define U1DLM           (*((volatile unsigned char *) 0xE0010004))
+#define U1ACR           (*((volatile unsigned long *) 0xE0010020))
+#define U1FDR           (*((volatile unsigned long *) 0xE0010028))
+#define U1TER           (*((volatile unsigned char *) 0xE0010030))
+
+/* I2C Interface 0 */
+#define I2C0CONSET      (*((volatile unsigned char *) 0xE001C000))
+#define I2C0STAT        (*((volatile unsigned char *) 0xE001C004))
+#define I2C0DAT         (*((volatile unsigned char *) 0xE001C008))
+#define I2C0ADR         (*((volatile unsigned char *) 0xE001C00C))
+#define I2C0SCLH        (*((volatile unsigned short*) 0xE001C010))
+#define I2C0SCLL        (*((volatile unsigned short*) 0xE001C014))
+#define I2C0CONCLR      (*((volatile unsigned char *) 0xE001C018))
+
+/* I2C Interface 1 */
+#define I2C1CONSET      (*((volatile unsigned char *) 0xE005C000))
+#define I2C1STAT        (*((volatile unsigned char *) 0xE005C004))
+#define I2C1DAT         (*((volatile unsigned char *) 0xE005C008))
+#define I2C1ADR         (*((volatile unsigned char *) 0xE005C00C))
+#define I2C1SCLH        (*((volatile unsigned short*) 0xE005C010))
+#define I2C1SCLL        (*((volatile unsigned short*) 0xE005C014))
+#define I2C1CONCLR      (*((volatile unsigned char *) 0xE005C018))
+
+/* SPI0 (Serial Peripheral Interface 0) */
+#define S0SPCR          (*((volatile unsigned short*) 0xE0020000))
+#define S0SPSR          (*((volatile unsigned char *) 0xE0020004))
+#define S0SPDR          (*((volatile unsigned short*) 0xE0020008))
+#define S0SPCCR         (*((volatile unsigned char *) 0xE002000C))
+#define S0SPINT         (*((volatile unsigned char *) 0xE002001C))
+
+/* SSP Controller (SPI1) */
+#define SSPCR0          (*((volatile unsigned short*) 0xE0068000))
+#define SSPCR1          (*((volatile unsigned char *) 0xE0068004))
+#define SSPDR           (*((volatile unsigned short*) 0xE0068008))
+#define SSPSR           (*((volatile unsigned char *) 0xE006800C))
+#define SSPCPSR         (*((volatile unsigned char *) 0xE0068010))
+#define SSPIMSC         (*((volatile unsigned char *) 0xE0068014))
+#define SSPRIS          (*((volatile unsigned char *) 0xE0068018))
+#define SSPMIS          (*((volatile unsigned char *) 0xE006801C))
+#define SSPICR          (*((volatile unsigned char *) 0xE0068020))
+
+/* Real Time Clock */
+#define ILR             (*((volatile unsigned char *) 0xE0024000))
+#define CTC             (*((volatile unsigned short*) 0xE0024004))
+#define CCR             (*((volatile unsigned char *) 0xE0024008))
+#define CIIR            (*((volatile unsigned char *) 0xE002400C))
+#define AMR             (*((volatile unsigned char *) 0xE0024010))
+#define CTIME0          (*((volatile unsigned long *) 0xE0024014))
+#define CTIME1          (*((volatile unsigned long *) 0xE0024018))
+#define CTIME2          (*((volatile unsigned long *) 0xE002401C))
+#define SEC             (*((volatile unsigned char *) 0xE0024020))
+#define MIN             (*((volatile unsigned char *) 0xE0024024))
+#define HOUR            (*((volatile unsigned char *) 0xE0024028))
+#define DOM             (*((volatile unsigned char *) 0xE002402C))
+#define DOW             (*((volatile unsigned char *) 0xE0024030))
+#define DOY             (*((volatile unsigned short*) 0xE0024034))
+#define MONTH           (*((volatile unsigned char *) 0xE0024038))
+#define YEAR            (*((volatile unsigned short*) 0xE002403C))
+#define ALSEC           (*((volatile unsigned char *) 0xE0024060))
+#define ALMIN           (*((volatile unsigned char *) 0xE0024064))
+#define ALHOUR          (*((volatile unsigned char *) 0xE0024068))
+#define ALDOM           (*((volatile unsigned char *) 0xE002406C))
+#define ALDOW           (*((volatile unsigned char *) 0xE0024070))
+#define ALDOY           (*((volatile unsigned short*) 0xE0024074))
+#define ALMON           (*((volatile unsigned char *) 0xE0024078))
+#define ALYEAR          (*((volatile unsigned short*) 0xE002407C))
+#define PREINT          (*((volatile unsigned short*) 0xE0024080))
+#define PREFRAC         (*((volatile unsigned short*) 0xE0024084))
+
+/* A/D Converter 0 (AD0) */
+#define AD0CR           (*((volatile unsigned long *) 0xE0034000))
+#define AD0GDR          (*((volatile unsigned long *) 0xE0034004))
+#define AD0STAT         (*((volatile unsigned long *) 0xE0034030))
+#define AD0INTEN        (*((volatile unsigned long *) 0xE003400C))
+#define AD0DR0          (*((volatile unsigned long *) 0xE0034010))
+#define AD0DR1          (*((volatile unsigned long *) 0xE0034014))
+#define AD0DR2          (*((volatile unsigned long *) 0xE0034018))
+#define AD0DR3          (*((volatile unsigned long *) 0xE003401C))
+#define AD0DR4          (*((volatile unsigned long *) 0xE0034020))
+#define AD0DR5          (*((volatile unsigned long *) 0xE0034024))
+#define AD0DR6          (*((volatile unsigned long *) 0xE0034028))
+#define AD0DR7          (*((volatile unsigned long *) 0xE003402C))
+
+/* A/D Converter 1 (AD1) */
+#define AD1CR           (*((volatile unsigned long *) 0xE0060000))
+#define AD1GDR          (*((volatile unsigned long *) 0xE0060004))
+#define AD1STAT         (*((volatile unsigned long *) 0xE0060030))
+#define AD1INTEN        (*((volatile unsigned long *) 0xE006000C))
+#define AD1DR0          (*((volatile unsigned long *) 0xE0060010))
+#define AD1DR1          (*((volatile unsigned long *) 0xE0060014))
+#define AD1DR2          (*((volatile unsigned long *) 0xE0060018))
+#define AD1DR3          (*((volatile unsigned long *) 0xE006001C))
+#define AD1DR4          (*((volatile unsigned long *) 0xE0060020))
+#define AD1DR5          (*((volatile unsigned long *) 0xE0060024))
+#define AD1DR6          (*((volatile unsigned long *) 0xE0060028))
+#define AD1DR7          (*((volatile unsigned long *) 0xE006002C))
+
+/* A/D Converter Global */
+#define ADGSR           (*((volatile unsigned long *) 0xE0034008))
+
+/* D/A Converter */
+#define DACR            (*((volatile unsigned long *) 0xE006C000))
+
+/* Watchdog */
+#define WDMOD           (*((volatile unsigned char *) 0xE0000000))
+#define WDTC            (*((volatile unsigned long *) 0xE0000004))
+#define WDFEED          (*((volatile unsigned char *) 0xE0000008))
+#define WDTV            (*((volatile unsigned long *) 0xE000000C))
+
+/* USB Controller */
+#define USBIntSt        (*((volatile unsigned long *) 0xE01FC1C0))
+#define USBDevIntSt     (*((volatile unsigned long *) 0xE0090000))
+#define USBDevIntEn     (*((volatile unsigned long *) 0xE0090004))
+#define USBDevIntClr    (*((volatile unsigned long *) 0xE0090008))
+#define USBDevIntSet    (*((volatile unsigned long *) 0xE009000C))
+#define USBDevIntPri    (*((volatile unsigned char *) 0xE009002C))
+#define USBEpIntSt      (*((volatile unsigned long *) 0xE0090030))
+#define USBEpIntEn      (*((volatile unsigned long *) 0xE0090034))
+#define USBEpIntClr     (*((volatile unsigned long *) 0xE0090038))
+#define USBEpIntSet     (*((volatile unsigned long *) 0xE009003C))
+#define USBEpIntPri     (*((volatile unsigned long *) 0xE0090040))
+#define USBReEp         (*((volatile unsigned long *) 0xE0090044))
+#define USBEpInd        (*((volatile unsigned long *) 0xE0090048))
+#define USBMaxPSize     (*((volatile unsigned long *) 0xE009004C))
+#define USBRxData       (*((volatile unsigned long *) 0xE0090018))
+#define USBRxPLen       (*((volatile unsigned long *) 0xE0090020))
+#define USBTxData       (*((volatile unsigned long *) 0xE009001C))
+#define USBTxPLen       (*((volatile unsigned long *) 0xE0090024))
+#define USBCtrl         (*((volatile unsigned long *) 0xE0090028))
+#define USBCmdCode      (*((volatile unsigned long *) 0xE0090010))
+#define USBCmdData      (*((volatile unsigned long *) 0xE0090014))
+#define USBDMARSt       (*((volatile unsigned long *) 0xE0090050))
+#define USBDMARClr      (*((volatile unsigned long *) 0xE0090054))
+#define USBDMARSet      (*((volatile unsigned long *) 0xE0090058))
+#define USBUDCAH        (*((volatile unsigned long *) 0xE0090080))
+#define USBEpDMASt      (*((volatile unsigned long *) 0xE0090084))
+#define USBEpDMAEn      (*((volatile unsigned long *) 0xE0090088))
+#define USBEpDMADis     (*((volatile unsigned long *) 0xE009008C))
+#define USBDMAIntSt     (*((volatile unsigned long *) 0xE0090090))
+#define USBDMAIntEn     (*((volatile unsigned long *) 0xE0090094))
+#define USBEoTIntSt     (*((volatile unsigned long *) 0xE00900A0))
+#define USBEoTIntClr    (*((volatile unsigned long *) 0xE00900A4))
+#define USBEoTIntSet    (*((volatile unsigned long *) 0xE00900A8))
+#define USBNDDRIntSt    (*((volatile unsigned long *) 0xE00900AC))
+#define USBNDDRIntClr   (*((volatile unsigned long *) 0xE00900B0))
+#define USBNDDRIntSet   (*((volatile unsigned long *) 0xE00900B4))
+#define USBSysErrIntSt  (*((volatile unsigned long *) 0xE00900B8))
+#define USBSysErrIntClr (*((volatile unsigned long *) 0xE00900BC))
+#define USBSysErrIntSet (*((volatile unsigned long *) 0xE00900C0))
+
+#define VIC_BASE_ADDR	0xFFFFF000
+
+enum LPC214x_INT
+{
+	WDT_INT	= 0,
+	SW_INT_reserved,
+	DbgCommRx_INT,
+	DbgCommTx_INT,
+	TIMER0_INT,
+	TIMER1_INT,
+	UART0_INT,
+	UART1_INT,
+	PWM0_INT,
+	I2C0_INT,
+	SP0_INT,
+	SP1_INT,
+	PLL_INT,
+	RTC_INT,
+	EINT0_INT,
+	EINT1_INT,
+	EINT2_INT,
+	EINT3_INT,
+	ADC0_INT,
+	I2C1_INT,
+	BOD_INT,
+	ADC1_INT,
+	USB_INT
+};
+
+#endif  // __LPC214x_H

+ 102 - 0
libcpu/arm/lpc214x/context_gcc.S

@@ -0,0 +1,102 @@
+.global rt_hw_interrupt_disable
+.global rt_hw_interrupt_enable
+.global rt_hw_context_switch
+.global rt_hw_context_switch_to
+.global rt_hw_context_switch_interrupt
+
+.equ  NOINT, 0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ 关闭中断,关闭前返回CPSR寄存器值
+ */
+rt_hw_interrupt_disable:
+	//EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	//ENDP
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+  恢复中断状态
+ */
+rt_hw_interrupt_enable:
+	//EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	//ENDP
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ 进行线程的上下文切换
+ */
+rt_hw_context_switch:
+	//EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			/* push pc (lr should be pushed in place of PC) */
+							    /* 把LR寄存器压入栈(这个函数返回后的下一个执行处) */
+	STMFD	sp!, {r0-r12, lr}	/* push lr & register file */
+								/*  把R0 – R12以及LR压入栈 */
+
+	MRS		r4, cpsr			/*  读取CPSR寄存器到R4寄存器 */
+	STMFD	sp!, {r4}			/* push cpsr */
+							    /* 把R4寄存器压栈(即上一指令取出的CPSR寄存器) */
+	MRS		r4, spsr		    /* 读取SPSR寄存器到R4寄存器 */
+	STMFD	sp!, {r4}			/* push spsr */
+								/* 把R4寄存器压栈(即SPSR寄存器) */
+
+	STR	sp, [r0]				/* store sp in preempted tasks TCB */
+								/*  把栈指针更新到TCB的sp,是由R0传入此函数 */
+								/*  到这里换出线程的上下文都保存在栈中 */
+	LDR	sp, [r1]				/* get new task stack pointer */
+								/*  载入切换到线程的TCB的sp */
+								/*  从切换到线程的栈中恢复上下文,次序和保存的时候刚好相反 */
+
+	LDMFD	sp!, {r4}			/* pop new task spsr */
+								/* 出栈到R4寄存器(保存了SPSR寄存器) */
+	MSR	spsr_cxsf, r4			/* 恢复SPSR寄存器 */
+	LDMFD	sp!, {r4}			/* pop new task cpsr */
+								/* 出栈到R4寄存器(保存了CPSR寄存器) */
+	MSR	cpsr_cxsf, r4			/*  恢复CPSR寄存器 */
+
+	LDMFD	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
+									/* 对R0 – R12及LR、PC进行恢复 */
+	//ENDP
+
+rt_hw_context_switch_to:
+	//EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				/* get new task stack pointer */
+								/* 获得切换到线程的SP指针 */
+
+	LDMFD	sp!, {r4}			/* pop new task spsr */
+								/* 出栈R4寄存器(保存了SPSR寄存器值) */
+	MSR	spsr_cxsf, r4			/* 恢复SPSR寄存器 */
+	LDMFD	sp!, {r4}			/* pop new task cpsr */
+								/* 出栈R4寄存器(保存了CPSR寄存器值) */
+	MSR	cpsr_cxsf, r4			/* 恢复CPSR寄存器 */
+
+	LDMFD	sp!, {r0-r12, lr, pc}	/* pop new task r0-r12, lr & pc */
+									/* 恢复R0 – R12,LR及PC寄存器 */
+	//ENDP
+
+rt_hw_context_switch_interrupt:
+	//EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]						/* 载入中断中切换标致地址 */
+	CMP r3, #1							/* 等于 1 ?*/
+	BEQ _reswitch						/* 如果等于1,跳转到_reswitch*/
+	MOV r3, #1							/* set rt_thread_switch_interrput_flag to 1*/
+										/* 设置中断中切换标志位1 */
+	STR r3, [r2]						/* */
+	LDR r2, =rt_interrupt_from_thread	/* set rt_interrupt_from_thread*/
+	STR r0, [r2]						/* 保存切换出线程栈指针*/
+_reswitch:
+	LDR r2, =rt_interrupt_to_thread		/* set rt_interrupt_to_thread*/
+	STR r1, [r2]						/* 保存切换到线程栈指针*/
+	BX	lr
+	//ENDP
+
+	//END

+ 107 - 0
libcpu/arm/lpc214x/context_rvds.s

@@ -0,0 +1,107 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-20     Bernard      first version
+; */
+
+NOINT	EQU		0xc0	; disable interrupt in psr
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	ARM
+	REQUIRE8
+	PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable	PROC
+	EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable	PROC
+	EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch	PROC
+	EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
+	STMFD	sp!, {r0-r12, lr}	; push lr & register file
+
+	MRS		r4, cpsr
+	STMFD	sp!, {r4}			; push cpsr
+	MRS		r4, spsr
+	STMFD	sp!, {r4}			; push spsr
+
+	STR	sp, [r0]				; store sp in preempted tasks TCB
+	LDR	sp, [r1]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to	PROC
+	EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt	PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]
+	CMP r3, #1
+	BEQ _reswitch
+	MOV r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR r3, [r2]
+	LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR r0, [r2]
+_reswitch
+	LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR r1, [r2]
+	BX	lr
+	ENDP
+
+	END

+ 42 - 0
libcpu/arm/lpc214x/cpu.c

@@ -0,0 +1,42 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "lpc214x.h"
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/

+ 105 - 0
libcpu/arm/lpc214x/interrupt.c

@@ -0,0 +1,105 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rtthread.h>
+#include "lpc214x.h"
+
+#define MAX_HANDLERS	32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	rt_base_t index;
+	rt_uint32_t *vect_addr, *vect_ctl;
+    
+	/* initialize VIC*/
+	VICIntEnClr = 0xffffffff;
+	VICVectAddr = 0;
+	/* set all to IRQ */
+	VICIntSelect = 0;
+
+	for (index = 0; index < MAX_HANDLERS; index ++)
+	{
+		vect_addr 	= (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (index << 2));
+		vect_ctl 	= (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (index << 2));
+
+		*vect_addr 	= (rt_uint32_t)rt_hw_interrupt_handler;
+		*vect_ctl 	= 0xF;
+	}
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	VICIntEnClr = (1 << vector);
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	VICIntEnable = (1 << vector);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	if(vector >= 0 && vector < MAX_HANDLERS)
+	{
+		/* get VIC address */
+		rt_uint32_t* vect_addr 	= (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + (vector << 2));
+		rt_uint32_t* vect_ctl 	= (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + (vector << 2));
+
+		/* assign IRQ slot and enable this slot */
+		*vect_ctl = 0x20 | (vector & 0x1F);
+
+		if (old_handler != RT_NULL) *old_handler = (rt_isr_handler_t) *vect_addr;
+		if (new_handler != RT_NULL) *vect_addr = (rt_uint32_t) new_handler;
+	}
+}
+
+/*@}*/

+ 387 - 0
libcpu/arm/lpc214x/serial.c

@@ -0,0 +1,387 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "lpc214x.h"
+#include "board.h"
+
+/* serial hardware register */
+#define REG8(d)			(*((volatile unsigned char *)(d)))
+#define REG32(d)		(*((volatile unsigned long *)(d)))
+
+#define UART_RBR(base)  REG8(base + 0x00)
+#define UART_THR(base)  REG8(base + 0x00)
+#define UART_IER(base)  REG32(base + 0x04)
+#define UART_IIR(base)  REG32(base + 0x08)
+#define UART_FCR(base)  REG8(base + 0x08)
+#define UART_LCR(base)  REG8(base + 0x0C)
+#define UART_MCR(base)  REG8(base + 0x10)
+#define UART_LSR(base)  REG8(base + 0x14)
+#define UART_MSR(base)  REG8(base + 0x18)
+#define UART_SCR(base)  REG8(base + 0x1C)
+#define UART_DLL(base)  REG8(base + 0x00)
+#define UART_DLM(base)  REG8(base + 0x04)
+#define UART_ACR(base)  REG32(base + 0x20)
+#define UART_FDR(base)  REG32(base + 0x28)
+#define UART_TER(base)  REG8(base + 0x30)
+
+/* LPC serial device */
+struct rt_lpcserial
+{
+	/* inherit from device */
+	struct rt_device parent;
+
+	rt_uint32_t hw_base;
+	rt_uint32_t irqno;
+	rt_uint32_t baudrate;
+
+	/* reception field */
+	rt_uint16_t save_index, read_index;
+	rt_uint8_t  rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+
+#ifdef RT_USING_UART1
+struct rt_lpcserial serial1;
+#endif
+#ifdef RT_USING_UART2
+struct rt_lpcserial serial2;
+#endif
+
+void rt_hw_serial_init(void);
+
+#define U0PINS  	0x00000005
+
+void rt_hw_uart_isr(struct rt_lpcserial* lpc_serial)
+{
+	UNUSED rt_uint32_t iir;
+
+	RT_ASSERT(lpc_serial != RT_NULL)
+		
+	if (UART_LSR(lpc_serial->hw_base) & 0x01)
+	{
+		rt_base_t level;
+
+		while (UART_LSR(lpc_serial->hw_base) & 0x01)
+		{
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+
+			/* read character */
+			lpc_serial->rx_buffer[lpc_serial->save_index] = 
+				UART_RBR(lpc_serial->hw_base);
+			lpc_serial->save_index ++;
+			if (lpc_serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+				lpc_serial->save_index = 0;
+			
+			/* if the next position is read index, discard this 'read char' */
+			if (lpc_serial->save_index == lpc_serial->read_index)
+			{
+				lpc_serial->read_index ++;
+				if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					lpc_serial->read_index = 0;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+		}
+
+		/* invoke callback */
+		if(lpc_serial->parent.rx_indicate != RT_NULL)
+		{
+		  lpc_serial->parent.rx_indicate(&lpc_serial->parent, 1);
+		}
+	}
+
+	/* clear interrupt source */
+	iir = UART_IIR(lpc_serial->hw_base);
+
+	/* acknowledge Interrupt */
+	VICVectAddr = 0;
+}
+
+#ifdef RT_USING_UART1
+void rt_hw_uart_isr_1(int irqno)
+{
+	/* get lpc serial device */
+	rt_hw_uart_isr(&serial1);
+}	
+#endif
+
+#ifdef RT_USING_UART2
+void rt_hw_uart_isr_2(int irqno)
+{
+	/* get lpc serial device */
+	rt_hw_uart_isr(&serial2);
+}	
+#endif
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_lpcserial* lpc_serial;
+	lpc_serial = (struct rt_lpcserial*) dev;
+	
+	RT_ASSERT(lpc_serial != RT_NULL);
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+	    /* init UART rx interrupt */
+    	UART_IER(lpc_serial->hw_base) = 0x01;
+
+		/* install ISR */
+		if (lpc_serial->irqno == UART0_INT)
+		{
+#ifdef RT_USING_UART1
+		    rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_1, RT_NULL);
+#endif
+		}
+		else
+		{
+#ifdef RT_USING_UART2
+		    rt_hw_interrupt_install(lpc_serial->irqno, rt_hw_uart_isr_2, RT_NULL);
+#endif
+		}
+
+	    rt_hw_interrupt_umask(lpc_serial->irqno);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	struct rt_lpcserial* lpc_serial;
+	lpc_serial = (struct rt_lpcserial*) dev;
+	
+	RT_ASSERT(lpc_serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* disable UART rx interrupt */
+		UART_IER(lpc_serial->hw_base) = 0x00;
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_lpcserial *lpc_serial = (struct rt_lpcserial*)dev;
+	RT_ASSERT(lpc_serial != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (lpc_serial->read_index != lpc_serial->save_index)
+			{
+				*ptr = lpc_serial->rx_buffer[lpc_serial->read_index];
+
+				lpc_serial->read_index ++;
+				if (lpc_serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					lpc_serial->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++; size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+	{
+		/* not support right now */
+		RT_ASSERT(0);
+	}
+
+	/* polling mode */
+	while (size && (UART_LSR(lpc_serial->hw_base) & 0x01))
+	{
+		/* Read Character */
+		*ptr = UART_RBR(lpc_serial->hw_base);
+		
+		ptr  ++;
+		size --;
+	}
+
+	return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	struct rt_lpcserial* lpc_serial;
+	char *ptr;
+
+	lpc_serial = (struct rt_lpcserial*) dev;
+	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+	{
+		/* not support */
+		RT_ASSERT(0);
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
+	{
+		/* not support */
+		RT_ASSERT(0);
+	}
+
+	/* polling write */
+	ptr = (char *)buffer;
+	
+	if (dev->flag & RT_DEVICE_FLAG_STREAM)
+	{
+		/* stream mode */
+		while (size)
+		{
+			if (*ptr == '\n')
+			{
+				while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+				UART_THR(lpc_serial->hw_base) = '\r';
+			}
+
+			while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+			UART_THR(lpc_serial->hw_base) = *ptr;
+			
+			ptr ++;
+			size --;
+		}
+	}
+	else
+	{
+		while (size)
+		{
+			while (!(UART_LSR(lpc_serial->hw_base) & 0x20));
+			UART_THR(lpc_serial->hw_base) = *ptr;
+			
+			ptr ++;
+			size --;
+		}
+	}
+	
+	return (rt_size_t) ptr - (rt_size_t) buffer;
+}
+
+void rt_hw_serial_init(void)
+{
+	struct rt_lpcserial* lpc_serial;
+	
+#ifdef RT_USING_UART1
+	lpc_serial = &serial1;
+	
+	lpc_serial->parent.type = RT_Device_Class_Char;
+	
+	lpc_serial->hw_base = 0xE000C000;
+	lpc_serial->baudrate = 115200;
+	lpc_serial->irqno = UART0_INT;
+	
+	rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
+	lpc_serial->read_index = lpc_serial->save_index = 0;
+
+	/* Enable UART0 RxD and TxD pins */
+  	PINSEL0 |= 0x05;
+
+	/* 8 bits, no Parity, 1 Stop bit */
+	UART_LCR(lpc_serial->hw_base) = 0x83;
+	
+	/* Setup Baudrate */
+	UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
+	UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
+
+	/* DLAB = 0 */
+	UART_LCR(lpc_serial->hw_base) = 0x03;
+
+	lpc_serial->parent.init 	= rt_serial_init;
+	lpc_serial->parent.open 	= rt_serial_open;
+	lpc_serial->parent.close    = rt_serial_close;
+	lpc_serial->parent.read 	= rt_serial_read;
+	lpc_serial->parent.write    = rt_serial_write;
+	lpc_serial->parent.control  = rt_serial_control;
+	lpc_serial->parent.private  = RT_NULL;
+
+	rt_device_register(&lpc_serial->parent, 
+		"uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+#ifdef RT_USING_UART2
+	lpc_serial = &serial2;
+	
+	lpc_serial->parent.type = RT_Device_Class_Char;
+
+	lpc_serial->hw_base = 0xE0010000;
+	lpc_serial->baudrate = 115200;
+	lpc_serial->irqno = UART1_INT;
+
+	rt_memset(lpc_serial->rx_buffer, 0, sizeof(lpc_serial->rx_buffer));
+	lpc_serial->read_index = lpc_serial->save_index = 0;
+
+	/* Enable UART1 RxD and TxD pins */
+  	PINSEL0 |= 0x05 << 16;
+
+	/* 8 bits, no Parity, 1 Stop bit */
+	UART_LCR(lpc_serial->hw_base) = 0x83;
+	
+	/* Setup Baudrate */
+	UART_DLL(lpc_serial->hw_base) = (PCLK/16/lpc_serial->baudrate) & 0xFF;
+	UART_DLM(lpc_serial->hw_base) = ((PCLK/16/lpc_serial->baudrate) >> 8) & 0xFF;
+
+	/* DLAB = 0 */
+	UART_LCR(lpc_serial->hw_base) = 0x03;
+
+	lpc_serial->parent.init 	= rt_serial_init;
+	lpc_serial->parent.open 	= rt_serial_open;
+	lpc_serial->parent.close    = rt_serial_close;
+	lpc_serial->parent.read 	= rt_serial_read;
+	lpc_serial->parent.write    = rt_serial_write;
+	lpc_serial->parent.control  = rt_serial_control;
+	lpc_serial->parent.private  = RT_NULL;
+
+	rt_device_register(&lpc_serial->parent, 
+		"uart2", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+}
+
+/*@}*/

+ 61 - 0
libcpu/arm/lpc214x/stack.c

@@ -0,0 +1,61 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      the first version
+ */
+#include <rtthread.h>
+
+#define SVCMODE		0x13
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk) 	 = (unsigned long)tentry;		/* entry point */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 508 - 0
libcpu/arm/lpc214x/start_rvds.s

@@ -0,0 +1,508 @@
+;/*****************************************************************************/
+;/* STARTUP.S: Startup file for Philips LPC2000                               */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>>                          */ 
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools.                   */
+;/* Copyright (c) 2005-2007 Keil Software. All rights reserved.               */
+;/* This software may only be used under the terms of a valid, current,       */
+;/* end user licence from KEIL for a compatible version of KEIL software      */
+;/* development tools. Nothing else gives you the right to use this software. */
+;/*****************************************************************************/
+
+
+;/*
+; *  The STARTUP.S code is executed after CPU Reset. This file may be 
+; *  translated with the following SET symbols. In uVision these SET 
+; *  symbols are entered under Options - ASM - Define.
+; *
+; *  REMAP: when set the startup code initializes the register MEMMAP 
+; *  which overwrites the settings of the CPU configuration pins. The 
+; *  startup and interrupt vectors are remapped from:
+; *     0x00000000  default setting (not remapped)
+; *     0x80000000  when EXTMEM_MODE is used
+; *     0x40000000  when RAM_MODE is used
+; *
+; *  EXTMEM_MODE: when set the device is configured for code execution
+; *  from external memory starting at address 0x80000000.
+; *
+; *  RAM_MODE: when set the device is configured for code execution
+; *  from on-chip RAM starting at address 0x40000000.
+; *
+; *  EXTERNAL_MODE: when set the PIN2SEL values are written that enable
+; *  the external BUS at startup.
+; */
+
+
+; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+
+Mode_USR        EQU     0x10
+Mode_FIQ        EQU     0x11
+Mode_IRQ        EQU     0x12
+Mode_SVC        EQU     0x13
+Mode_ABT        EQU     0x17
+Mode_UND        EQU     0x1B
+Mode_SYS        EQU     0x1F
+
+I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
+F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
+
+
+;// <h> Stack Configuration (Stack Sizes in Bytes)
+;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
+;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
+;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
+;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
+;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
+;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
+;// </h>
+
+UND_Stack_Size  EQU     0x00000000
+SVC_Stack_Size  EQU     0x00000100
+ABT_Stack_Size  EQU     0x00000000
+FIQ_Stack_Size  EQU     0x00000000
+IRQ_Stack_Size  EQU     0x00000100
+USR_Stack_Size  EQU     0x00000100
+
+ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                         FIQ_Stack_Size + IRQ_Stack_Size)
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem       SPACE   USR_Stack_Size
+__initial_sp    SPACE   ISR_Stack_Size
+
+Stack_Top
+
+
+;// <h> Heap Configuration
+;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
+;// </h>
+
+Heap_Size       EQU     0x00000000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+; VPBDIV definitions
+VPBDIV          EQU     0xE01FC100      ; VPBDIV Address
+
+;// <e> VPBDIV Setup
+;// <i> Peripheral Bus Clock Rate
+;//   <o1.0..1>   VPBDIV: VPB Clock
+;//               <0=> VPB Clock = CPU Clock / 4
+;//               <1=> VPB Clock = CPU Clock
+;//               <2=> VPB Clock = CPU Clock / 2
+;//   <o1.4..5>   XCLKDIV: XCLK Pin
+;//               <0=> XCLK Pin = CPU Clock / 4
+;//               <1=> XCLK Pin = CPU Clock
+;//               <2=> XCLK Pin = CPU Clock / 2
+;// </e>
+VPBDIV_SETUP    EQU     0
+VPBDIV_Val      EQU     0x00000000
+
+
+; Phase Locked Loop (PLL) definitions
+PLL_BASE        EQU     0xE01FC080      ; PLL Base Address
+PLLCON_OFS      EQU     0x00            ; PLL Control Offset
+PLLCFG_OFS      EQU     0x04            ; PLL Configuration Offset
+PLLSTAT_OFS     EQU     0x08            ; PLL Status Offset
+PLLFEED_OFS     EQU     0x0C            ; PLL Feed Offset
+PLLCON_PLLE     EQU     (1<<0)          ; PLL Enable
+PLLCON_PLLC     EQU     (1<<1)          ; PLL Connect
+PLLCFG_MSEL     EQU     (0x1F<<0)       ; PLL Multiplier
+PLLCFG_PSEL     EQU     (0x03<<5)       ; PLL Divider
+PLLSTAT_PLOCK   EQU     (1<<10)         ; PLL Lock Status
+
+;// <e> PLL Setup
+;//   <o1.0..4>   MSEL: PLL Multiplier Selection
+;//               <1-32><#-1>
+;//               <i> M Value
+;//   <o1.5..6>   PSEL: PLL Divider Selection
+;//               <0=> 1   <1=> 2   <2=> 4   <3=> 8
+;//               <i> P Value
+;// </e>
+PLL_SETUP       EQU     1
+PLLCFG_Val      EQU     0x00000024
+
+
+; Memory Accelerator Module (MAM) definitions
+MAM_BASE        EQU     0xE01FC000      ; MAM Base Address
+MAMCR_OFS       EQU     0x00            ; MAM Control Offset
+MAMTIM_OFS      EQU     0x04            ; MAM Timing Offset
+
+;// <e> MAM Setup
+;//   <o1.0..1>   MAM Control
+;//               <0=> Disabled
+;//               <1=> Partially Enabled
+;//               <2=> Fully Enabled
+;//               <i> Mode
+;//   <o2.0..2>   MAM Timing
+;//               <0=> Reserved  <1=> 1   <2=> 2   <3=> 3
+;//               <4=> 4         <5=> 5   <6=> 6   <7=> 7
+;//               <i> Fetch Cycles
+;// </e>
+MAM_SETUP       EQU     1
+MAMCR_Val       EQU     0x00000002
+MAMTIM_Val      EQU     0x00000004
+
+
+; External Memory Controller (EMC) definitions
+EMC_BASE        EQU     0xFFE00000      ; EMC Base Address
+BCFG0_OFS       EQU     0x00            ; BCFG0 Offset
+BCFG1_OFS       EQU     0x04            ; BCFG1 Offset
+BCFG2_OFS       EQU     0x08            ; BCFG2 Offset
+BCFG3_OFS       EQU     0x0C            ; BCFG3 Offset
+
+;// <e> External Memory Controller (EMC)
+EMC_SETUP       EQU     0
+
+;//   <e> Bank Configuration 0 (BCFG0)
+;//     <o1.0..3>   IDCY: Idle Cycles <0-15>
+;//     <o1.5..9>   WST1: Wait States 1 <0-31>
+;//     <o1.11..15> WST2: Wait States 2 <0-31>
+;//     <o1.10>     RBLE: Read Byte Lane Enable
+;//     <o1.26>     WP: Write Protect
+;//     <o1.27>     BM: Burst ROM
+;//     <o1.28..29> MW: Memory Width  <0=>  8-bit  <1=> 16-bit
+;//                                   <2=> 32-bit  <3=> Reserved
+;//   </e>
+BCFG0_SETUP EQU         0
+BCFG0_Val   EQU         0x0000FBEF
+
+;//   <e> Bank Configuration 1 (BCFG1)
+;//     <o1.0..3>   IDCY: Idle Cycles <0-15>
+;//     <o1.5..9>   WST1: Wait States 1 <0-31>
+;//     <o1.11..15> WST2: Wait States 2 <0-31>
+;//     <o1.10>     RBLE: Read Byte Lane Enable
+;//     <o1.26>     WP: Write Protect
+;//     <o1.27>     BM: Burst ROM
+;//     <o1.28..29> MW: Memory Width  <0=>  8-bit  <1=> 16-bit
+;//                                   <2=> 32-bit  <3=> Reserved
+;//   </e>
+BCFG1_SETUP EQU         0
+BCFG1_Val   EQU         0x0000FBEF
+
+;//   <e> Bank Configuration 2 (BCFG2)
+;//     <o1.0..3>   IDCY: Idle Cycles <0-15>
+;//     <o1.5..9>   WST1: Wait States 1 <0-31>
+;//     <o1.11..15> WST2: Wait States 2 <0-31>
+;//     <o1.10>     RBLE: Read Byte Lane Enable
+;//     <o1.26>     WP: Write Protect
+;//     <o1.27>     BM: Burst ROM
+;//     <o1.28..29> MW: Memory Width  <0=>  8-bit  <1=> 16-bit
+;//                                   <2=> 32-bit  <3=> Reserved
+;//   </e>
+BCFG2_SETUP EQU         0
+BCFG2_Val   EQU         0x0000FBEF
+
+;//   <e> Bank Configuration 3 (BCFG3)
+;//     <o1.0..3>   IDCY: Idle Cycles <0-15>
+;//     <o1.5..9>   WST1: Wait States 1 <0-31>
+;//     <o1.11..15> WST2: Wait States 2 <0-31>
+;//     <o1.10>     RBLE: Read Byte Lane Enable
+;//     <o1.26>     WP: Write Protect
+;//     <o1.27>     BM: Burst ROM
+;//     <o1.28..29> MW: Memory Width  <0=>  8-bit  <1=> 16-bit
+;//                                   <2=> 32-bit  <3=> Reserved
+;//   </e>
+BCFG3_SETUP EQU         0
+BCFG3_Val   EQU         0x0000FBEF
+
+;// </e> End of EMC
+
+
+; External Memory Pins definitions
+PINSEL2         EQU     0xE002C014      ; PINSEL2 Address
+PINSEL2_Val     EQU     0x0E6149E4      ; CS0..3, OE, WE, BLS0..3, 
+                                        ; D0..31, A2..23, JTAG Pins
+
+
+                PRESERVE8
+                
+
+; Area Definition and Entry Point
+;  Startup Code must be linked first at Address at which it expects to run.
+
+                AREA    RESET, CODE, READONLY
+                ARM
+
+
+; Exception Vectors
+;  Mapped to Address 0.
+;  Absolute addressing mode must be used.
+;  Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors         LDR     PC, Reset_Addr         
+                LDR     PC, Undef_Addr
+                LDR     PC, SWI_Addr
+                LDR     PC, PAbt_Addr
+                LDR     PC, DAbt_Addr
+                NOP                            ; Reserved Vector 
+               	LDR     PC, IRQ_Addr
+                LDR     PC, FIQ_Addr
+
+Reset_Addr      DCD     Reset_Handler
+Undef_Addr      DCD     Undef_Handler
+SWI_Addr        DCD     SWI_Handler
+PAbt_Addr       DCD     PAbt_Handler
+DAbt_Addr       DCD     DAbt_Handler
+                DCD     0                      ; Reserved Address 
+IRQ_Addr        DCD     IRQ_Handler
+FIQ_Addr        DCD     FIQ_Handler
+
+Undef_Handler   B       Undef_Handler
+SWI_Handler     B       SWI_Handler
+PAbt_Handler    B       PAbt_Handler
+DAbt_Handler    B       DAbt_Handler
+FIQ_Handler     B       FIQ_Handler
+
+
+; Reset Handler
+
+                EXPORT  Reset_Handler
+Reset_Handler   
+
+
+; Setup External Memory Pins
+                IF      :DEF:EXTERNAL_MODE
+                LDR     R0, =PINSEL2
+                LDR     R1, =PINSEL2_Val
+                STR     R1, [R0]
+                ENDIF
+
+
+; Setup External Memory Controller
+                IF      EMC_SETUP <> 0
+                LDR     R0, =EMC_BASE
+
+                IF      BCFG0_SETUP <> 0
+                LDR     R1, =BCFG0_Val
+                STR     R1, [R0, #BCFG0_OFS]
+                ENDIF
+
+                IF      BCFG1_SETUP <> 0
+                LDR     R1, =BCFG1_Val
+                STR     R1, [R0, #BCFG1_OFS]
+                ENDIF
+
+                IF      BCFG2_SETUP <> 0
+                LDR     R1, =BCFG2_Val
+                STR     R1, [R0, #BCFG2_OFS]
+                ENDIF
+
+                IF      BCFG3_SETUP <> 0
+                LDR     R1, =BCFG3_Val
+                STR     R1, [R0, #BCFG3_OFS]
+                ENDIF
+
+                ENDIF   ; EMC_SETUP
+
+
+; Setup VPBDIV
+                IF      VPBDIV_SETUP <> 0
+                LDR     R0, =VPBDIV
+                LDR     R1, =VPBDIV_Val
+                STR     R1, [R0]
+                ENDIF
+
+
+; Setup PLL
+                IF      PLL_SETUP <> 0
+                LDR     R0, =PLL_BASE
+                MOV     R1, #0xAA
+                MOV     R2, #0x55
+
+;  Configure and Enable PLL
+                MOV     R3, #PLLCFG_Val
+                STR     R3, [R0, #PLLCFG_OFS] 
+                MOV     R3, #PLLCON_PLLE
+                STR     R3, [R0, #PLLCON_OFS]
+                STR     R1, [R0, #PLLFEED_OFS]
+                STR     R2, [R0, #PLLFEED_OFS]
+
+;  Wait until PLL Locked
+PLL_Loop        LDR     R3, [R0, #PLLSTAT_OFS]
+                ANDS    R3, R3, #PLLSTAT_PLOCK
+                BEQ     PLL_Loop
+
+;  Switch to PLL Clock
+                MOV     R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
+                STR     R3, [R0, #PLLCON_OFS]
+                STR     R1, [R0, #PLLFEED_OFS]
+                STR     R2, [R0, #PLLFEED_OFS]
+                ENDIF   ; PLL_SETUP
+
+
+; Setup MAM
+                IF      MAM_SETUP <> 0
+                LDR     R0, =MAM_BASE
+                MOV     R1, #MAMTIM_Val
+                STR     R1, [R0, #MAMTIM_OFS] 
+                MOV     R1, #MAMCR_Val
+                STR     R1, [R0, #MAMCR_OFS] 
+                ENDIF   ; MAM_SETUP
+
+
+; Memory Mapping (when Interrupt Vectors are in RAM)
+MEMMAP          EQU     0xE01FC040      ; Memory Mapping Control
+                IF      :DEF:REMAP
+                LDR     R0, =MEMMAP
+                IF      :DEF:EXTMEM_MODE
+                MOV     R1, #3
+                ELIF    :DEF:RAM_MODE
+                MOV     R1, #2
+                ELSE
+                MOV     R1, #1
+                ENDIF
+                STR     R1, [R0]
+                ENDIF
+
+
+; Initialise Interrupt System
+;  ...
+
+
+; Setup Stack for each mode
+
+                LDR     R0, =Stack_Top
+
+;  Enter Undefined Instruction Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #UND_Stack_Size
+
+;  Enter Abort Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #ABT_Stack_Size
+
+;  Enter FIQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #FIQ_Stack_Size
+
+;  Enter IRQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #IRQ_Stack_Size
+
+;  Enter Supervisor Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                ; SUB     R0, R0, #SVC_Stack_Size
+
+;  Enter User Mode and set its Stack Pointer
+				; RT-Thread does not use user mode
+                ; MSR     CPSR_c, #Mode_USR
+                IF      :DEF:__MICROLIB
+
+                EXPORT __initial_sp
+
+                ELSE
+
+                ; MOV     SP, R0
+                ; SUB     SL, SP, #USR_Stack_Size
+
+                ENDIF
+
+; Enter the C code
+
+                IMPORT  __main
+                LDR     R0, =__main
+                BX      R0
+
+				IMPORT rt_interrupt_enter
+				IMPORT rt_interrupt_leave
+				IMPORT rt_thread_switch_interrput_flag
+				IMPORT rt_interrupt_from_thread
+				IMPORT rt_interrupt_to_thread
+				IMPORT rt_hw_trap_irq
+
+IRQ_Handler		PROC
+				EXPORT IRQ_Handler
+				STMFD	sp!, {r0-r12,lr}
+				BL	rt_interrupt_enter
+				BL	rt_hw_trap_irq
+				BL	rt_interrupt_leave
+
+				; if rt_thread_switch_interrput_flag set, jump to
+				; rt_hw_context_switch_interrupt_do and don't return
+				LDR	r0, =rt_thread_switch_interrput_flag
+				LDR	r1, [r0]
+				CMP	r1, #1
+				BEQ	rt_hw_context_switch_interrupt_do
+
+				LDMFD	sp!, {r0-r12,lr}
+				SUBS	pc, lr, #4
+				ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do	PROC
+				EXPORT rt_hw_context_switch_interrupt_do
+				MOV		r1,  #0			; clear flag
+				STR		r1,  [r0]
+
+				LDMFD	sp!, {r0-r12,lr}; reload saved registers
+				STMFD	sp!, {r0-r3}	; save r0-r3
+				MOV		r1,  sp
+				ADD		sp,  sp, #16	; restore sp
+				SUB		r2,  lr, #4		; save old task's pc to r2
+
+				MRS		r3,  spsr		; get cpsr of interrupt thread
+
+				; switch to SVC mode and no interrupt
+                MSR     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+				STMFD	sp!, {r2}		; push old task's pc
+				STMFD	sp!, {r4-r12,lr}; push old task's lr,r12-r4
+				MOV		r4,  r1			; Special optimised code below
+				MOV		r5,  r3
+				LDMFD	r4!, {r0-r3}
+				STMFD	sp!, {r0-r3}	; push old task's r3-r0
+				STMFD	sp!, {r5}		; push old task's cpsr
+				MRS		r4,  spsr
+				STMFD	sp!, {r4}		; push old task's spsr
+
+				LDR		r4,  =rt_interrupt_from_thread
+				LDR		r5,  [r4]
+				STR		sp,  [r5]		; store sp in preempted tasks's TCB
+
+				LDR		r6,  =rt_interrupt_to_thread
+				LDR		r6,  [r6]
+				LDR		sp,  [r6]		; get new task's stack pointer
+			
+				LDMFD	sp!, {r4}		; pop new task's spsr
+				MSR		spsr_cxsf, r4
+				LDMFD	sp!, {r4}		; pop new task's psr
+				MSR		cpsr_cxsf, r4
+
+				LDMFD	sp!, {r0-r12,lr,pc}	; pop new task's r0-r12,lr & pc
+				ENDP
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+; User Initial Stack & Heap
+                AREA    |.text|, CODE, READONLY
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + USR_Stack_Size)
+                LDR     R2, = (Heap_Mem +      Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDIF
+
+                END

+ 350 - 0
libcpu/arm/lpc214x/startup_gcc.S

@@ -0,0 +1,350 @@
+	.extern main                               /* 引入外部C入口 */
+
+	.extern __bss_beg__
+	.extern __bss_end__
+	.extern __stack_end__
+	.extern __data_beg__
+	.extern __data_end__
+	.extern __data+beg_src__
+
+	.extern rt_interrupt_enter
+	.extern rt_interrupt_leave
+	.extern rt_thread_switch_interrput_flag
+	.extern rt_interrupt_from_thread
+	.extern rt_interrupt_to_thread
+	.extern rt_hw_trap_irq
+
+	.global start
+	.global endless_loop
+    .global rt_hw_context_switch_interrupt_do
+
+/************* 目标配置 *************/
+    .set  UND_STACK_SIZE, 0x00000004
+    .set  ABT_STACK_SIZE, 0x00000004
+    .set  FIQ_STACK_SIZE, 0x00000004
+    .set  IRQ_STACK_SIZE, 0x00000400
+    .set  SVC_STACK_SIZE, 0x00000400
+
+    .set  UND_Stack_Size, 0x00000004
+    .set  ABT_Stack_Size, 0x00000004
+    .set  FIQ_Stack_Size, 0x00000004
+    .set  IRQ_Stack_Size, 0x00000400
+    .set  SVC_Stack_Size, 0x00000400
+
+	/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
+    .set  MODE_USR, 0x10            /* User Mode */
+    .set  MODE_FIQ, 0x11            /* FIQ Mode */
+    .set  MODE_IRQ, 0x12            /* IRQ Mode */
+    .set  MODE_SVC, 0x13            /* Supervisor Mode */
+    .set  MODE_ABT, 0x17            /* Abort Mode */
+    .set  MODE_UND, 0x1B            /* Undefined Mode */
+    .set  MODE_SYS, 0x1F            /* System Mode */
+    .set  MODE_USR, 0x10            /* User Mode */
+    .set  Mode_FIQ, 0x11            /* FIQ Mode */
+    .set  Mode_IRQ, 0x12            /* IRQ Mode */
+    .set  Mode_SVC, 0x13            /* Supervisor Mode */
+    .set  Mode_ABT, 0x17            /* Abort Mode */
+    .set  Mode_UND, 0x1B            /* Undefined Mode */
+    .set  Mode_SYS, 0x1F            /* System Mode */
+
+    .equ  I_BIT, 0x80               /* when I bit is set, IRQ is disabled */
+    .equ  F_BIT, 0x40               /* when F bit is set, FIQ is disabled */
+    .equ  I_Bit, 0x80               /* when I bit is set, IRQ is disabled */
+    .equ  F_Bit, 0x40               /* when F bit is set, FIQ is disabled */
+
+    /* VPBDIV definitions*/
+    .equ  VPBDIV, 		0xE01FC100
+    .set  VPBDIV_VALUE,	0x00000000
+
+    /* Phase Locked Loop (PLL) definitions*/
+    .equ  PLL_BASE, 	0xE01FC080
+    .equ  PLLCON_OFS, 	0x00
+    .equ  PLLCFG_OFS, 	0x04
+    .equ  PLLSTAT_OFS, 	0x08
+    .equ  PLLFEED_OFS, 	0x0C
+
+    .equ PLLCON_PLLE,   (1<<0)      /* PLL Enable */
+    .equ PLLCON_PLLC,   (1<<1)      /* PLL Connect */
+    .equ PLLSTAT_LOCK,  (1<<10)     /* PLL Lock Status */
+    .equ PLLCFG_MSEL,   ((PLL_MUL - 1) << 0)
+    .equ PLLCFG_PSEL,	(0x02 << 5)
+    .equ PLLCFG_Val,	(PLLCFG_MSEL|PLLCFG_PSEL)
+
+    .equ  MEMMAP,		0xE01FC040     /*Memory Mapping Control*/
+
+
+    /* Memory Accelerator Module (MAM) definitions*/
+    .equ  MAM_BASE, 	0xE01FC000
+    .equ  MAMCR_OFS, 	0x00
+    .equ  MAMTIM_OFS, 	0x04
+    .equ  MAMCR_Val,    0x00000002
+    .equ  MAMTIM_Val,   0x00000004
+
+    .equ  VICIntEnClr,	0xFFFFF014
+    .equ  VICIntSelect,	0xFFFFF00C
+/************* 目标配置结束 *************/
+
+
+/* Setup the operating mode & stack.*/
+/* --------------------------------- */
+	.global _start, start, _reset, reset,
+	.func   _start,
+
+_start:
+start:
+_reset:
+reset:
+	.code 32
+	.align 0
+
+/************************* PLL_SETUP **********************************/
+#if (PLL_MUL>1)
+
+		ldr     r0, =PLL_BASE
+		mov		r1, #0xAA
+		mov		r2, #0x55
+
+/* Configure and Enable PLL */
+		mov     r3, #PLLCFG_Val
+		str     r3, [r0, #PLLCFG_OFS]
+		mov     r3, #PLLCON_PLLE
+		str     r3, [r0, #PLLCON_OFS]
+		str     r1, [r0, #PLLFEED_OFS]
+		str     r2, [r0, #PLLFEED_OFS]
+
+/*  Wait until PLL Locked */
+PLL_Locked_loop:
+		ldr     r3, [r0, #PLLSTAT_OFS]
+		ands    r3, r3, #PLLSTAT_LOCK
+		beq     PLL_Locked_loop
+
+/*  Switch to PLL Clock */
+		mov     r3, #(PLLCON_PLLE|PLLCON_PLLC)
+		str     r3, [r0, #PLLCON_OFS]
+		str     r1, [r0, #PLLFEED_OFS]
+		str     R2, [r0, #PLLFEED_OFS]
+
+#endif
+/************************* PLL_SETUP **********************************/
+
+/************************ Setup VPBDIV ********************************/
+		ldr		r0, =VPBDIV
+		ldr     r1, =VPBDIV_VALUE
+		str		r1, [r0]
+/************************ Setup VPBDIV ********************************/
+
+/************** Setup MAM **************/
+		ldr		r0, =MAM_BASE
+		mov		r1, #MAMTIM_Val
+		str		r1, [r0, #MAMTIM_OFS]
+		mov		r1, #MAMCR_Val
+		str		r1, [r0, #MAMCR_OFS]
+/************** Setup MAM **************/
+
+/************************ setup stack *********************************/
+    ldr   r0, .LC6                      /* LC6:__stack_end__ */
+    msr   CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
+    mov   sp, r0
+    sub   r0, r0, #UND_STACK_SIZE
+    msr   CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
+    mov   sp, r0
+    sub   r0, r0, #ABT_STACK_SIZE
+    msr   CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
+    mov   sp, r0
+    sub   r0, r0, #FIQ_STACK_SIZE
+    msr   CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
+    mov   sp, r0
+    sub   r0, r0, #IRQ_STACK_SIZE
+    msr   CPSR_c, #MODE_SVC|I_BIT|F_BIT  /* Supervisor Mode */
+    mov   sp, r0
+/************************ setup stack ********************************/
+
+/************************  Clear BSS  ********************************/
+	/* Clear BSS. */
+
+	mov     a2, #0			/* Fill value */
+	mov		fp, a2			/* Null frame pointer */
+	mov		r7, a2			/* Null frame pointer for Thumb */
+
+	ldr		r1, .LC1		/* Start of memory block */
+	ldr		r3, .LC2		/* End of memory block */
+	subs	r3, r3, r1      /* Length of block */
+	beq		.end_clear_loop
+	mov		r2, #0
+
+.clear_loop:
+	strb	r2, [r1], #1
+	subs	r3, r3, #1
+	bgt		.clear_loop
+
+.end_clear_loop:
+
+	/* Initialise data. */
+
+	ldr		r1, .LC3		/* Start of memory block */
+	ldr		r2, .LC4		/* End of memory block */
+	ldr		r3, .LC5
+	subs	r3, r3, r1		/* Length of block */
+	beq		.end_set_loop
+
+.set_loop:
+	ldrb	r4, [r2], #1
+	strb	r4, [r1], #1
+	subs	r3, r3, #1
+	bgt		.set_loop
+
+.end_set_loop:
+
+	mov		r0, #0          /* no arguments  */
+	mov		r1, #0          /* no argv either */
+
+	bl		main
+
+endless_loop:
+	b               endless_loop
+
+	.align 0
+
+	.LC1:
+	.word   __bss_beg__
+	.LC2:
+	.word   __bss_end__
+	.LC3:
+	.word   __data_beg__
+	.LC4:
+	.word   __data_beg_src__
+	.LC5:
+	.word   __data_end__
+	.LC6:
+	.word   __stack_end__
+/*********************** END Clear BSS  ******************************/
+
+/******************** 跳转到 main() ********************/
+	LDR     R0, =main       /* 获得main()入口地址 */
+	BX      R0              /* 长跳转到main()     */
+/******************** 跳转到 main() ********************/
+
+
+/* 本段为.startup段 在链接脚本中被链接到程序最开头 */
+.section .startup,"ax"
+    .code 32
+	.align 0
+
+	ldr   pc, __start					/* reset - _start			*/
+	ldr   pc, _undf						/* undefined - _undf		*/
+	ldr   pc, _swi			    		/* SWI - _swi				*/
+	ldr   pc, _pabt						/* program abort - _pabt	*/
+	ldr   pc, _dabt						/* data abort - _dabt		*/
+	//.word 0xB9205F80				    /* 默认		0xB9205F80		*/
+	.word 0xB8A06F58					/* 0xB8A06F58 全为          */
+	ldr   pc, __IRQ_Handler				/* IRQ - read the VIC		*/
+	ldr   pc, _fiq						/* FIQ - _fiq				*/
+
+__start:.word _start
+_undf:  .word __undf                    /* undefined				*/
+_swi:   .word __swi                     /* SWI						*/
+_pabt:  .word __pabt                    /* program abort			*/
+_dabt:  .word __dabt                    /* data abort				*/
+temp1:  .word 0
+__IRQ_Handler:  .word IRQ_Handler
+_fiq:   .word __fiq                     /* FIQ						*/
+
+__undf: b     .                         /* undefined				*/
+__swi : b     .
+__pabt: b     .                         /* program abort			*/
+__dabt: b     .                         /* data abort				*/
+__fiq : b     .  					    /* FIQ						*/
+
+/* IRQ入口 */
+IRQ_Handler :
+		stmfd	sp!, {r0-r12,lr} 			   /* 对R0 – R12,LR寄存器压栈      */
+		bl	rt_interrupt_enter	 			   /* 通知RT-Thread进入中断模式     */
+		bl	rt_hw_trap_irq		 			   /* 相应中断服务例程处理  	    */
+		bl	rt_interrupt_leave		           /* ; 通知RT-Thread要离开中断模式 */
+
+		/* 如果设置了rt_thread_switch_interrput_flag,进行中断中的线程上下文处理 */
+		ldr	r0, =rt_thread_switch_interrput_flag
+		ldr	r1, [r0]
+		cmp	r1, #1
+		beq	rt_hw_context_switch_interrupt_do  /* 中断中切换发生 */
+											   /* 如果跳转了,将不会回来 */
+		ldmfd	sp!, {r0-r12,lr}			   /* 恢复栈 */
+		subs	pc, lr, #4					   /* 从IRQ中返回 */
+
+/*
+* void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+* 中断结束后的上下文切换
+*/
+rt_hw_context_switch_interrupt_do:
+				mov	r1,  #0				/* clear flag */
+										/* 清楚中断中切换标志 */
+				str	r1,  [r0]			/* */
+
+				ldmfd	sp!, {r0-r12,lr}/* reload saved registers */
+										/* 先恢复被中断线程的上下文 */
+				stmfd	sp!, {r0-r3}	/* save r0-r3 */
+										/* 对R0 – R3压栈,因为后面会用到 */
+				mov	r1,  sp				/* 把此处的栈值保存到R1 */
+				add	sp,  sp, #16		/* restore sp */
+										/* 恢复IRQ的栈,后面会跳出IRQ模式 */
+				sub	r2,  lr, #4			/* save old task's pc to r2 */
+										/* 保存切换出线程的PC到R2 */
+
+				mrs	r3,  spsr			/* disable interrupt 保存中断前的CPSR到R3寄存器 */
+										/* 获得SPSR寄存器值 */
+				orr	r0,  r3, #I_BIT|F_BIT
+				msr	spsr_c, r0			/*  关闭SPSR中的IRQ/FIQ中断 */
+
+				ldr	r0,  =.+8		    /* 把当前地址+8载入到R0寄存器中 switch to interrupted task's stack */
+				movs pc,  r0            /* 退出IRQ模式,由于SPSR被设置成关中断模式 */
+										/* 所以从IRQ返回后,中断并没有打开
+										; R0寄存器中的位置实际就是下一条指令,
+										; 即PC继续往下走
+										; 此时
+										; 模式已经换成中断前的SVC模式,
+										; SP寄存器也是SVC模式下的栈寄存器
+										; R1保存IRQ模式下的栈指针
+										; R2保存切换出线程的PC
+										; R3保存切换出线程的CPSR */
+				stmfd	sp!, {r2}		/* push old task's pc */
+										/* 保存切换出任务的PC */
+				stmfd	sp!, {r4-r12,lr}/* push old task's lr,r12-r4 */
+										/* 保存R4 – R12,LR寄存器 */
+				mov	r4,  r1				/* Special optimised code below */
+										/* R1保存有压栈R0 – R3处的栈位置 */
+				mov	r5,  r3				/* R3切换出线程的CPSR */
+				ldmfd	r4!, {r0-r3}	/* 恢复R0 – R3 */
+				stmfd	sp!, {r0-r3}	/* push old task's r3-r0 */
+										/*  R0 – R3压栈到切换出线程 */
+				stmfd	sp!, {r5}		/* push old task's psr */
+										/* 切换出线程CPSR压栈 */
+				mrs	r4,  spsr
+				stmfd	sp!, {r4}		/* push old task's spsr */
+										/* 切换出线程SPSR压栈 */
+
+				ldr	r4,  =rt_interrupt_from_thread
+				ldr	r5,  [r4]
+				str	sp,  [r5]			/* store sp in preempted tasks's TCB */
+										/* 保存切换出线程的SP指针 */
+
+				ldr	r6,  =rt_interrupt_to_thread
+				ldr	r6,  [r6]
+				ldr	sp,  [r6]			/* get new task's stack pointer */
+										/* 获得切换到线程的栈 */
+
+				ldmfd	sp!, {r4}		/* pop new task's spsr */
+										/* 恢复SPSR */
+				msr	SPSR_cxsf, r4
+				ldmfd	sp!, {r4}		/* pop new task's psr */
+										/* 恢复CPSR */
+				msr	CPSR_cxsf, r4
+
+				ldmfd	sp!, {r0-r12,lr,pc}	/* pop new task's r0-r12,lr & pc */
+											/* 恢复R0 – R12,LR及PC寄存器 */
+
+/* 代码加密功能 */
+#if defined(CODE_PROTECTION)
+.org 0x01FC
+.word 0x87654321
+#endif
+

+ 40 - 0
libcpu/arm/lpc214x/trap.c

@@ -0,0 +1,40 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-25     Bernard      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "lpc214x.h"
+
+/**
+ * @addtogroup LPC214x
+ */
+/*@{*/
+
+void rt_hw_trap_irq()
+{
+	rt_isr_handler_t isr_func;
+	
+	isr_func = (rt_isr_handler_t) VICVectAddr;
+	isr_func(0);
+	
+	/* acknowledge Interrupt */
+	// VICVectAddr = 0;
+}
+
+void rt_hw_trap_fiq()
+{
+    rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/

+ 1201 - 0
libcpu/arm/lpc24xx/LPC24xx.h

@@ -0,0 +1,1201 @@
+/*
+ * File      : LPC2478.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     xuxinming    first version
+ */
+
+#ifndef __LPC24xx_H
+#define __LPC24xx_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+#define USERMODE	0x10
+#define FIQMODE		0x11
+#define IRQMODE		0x12
+#define SVCMODE		0x13
+#define ABORTMODE	0x17
+#define UNDEFMODE	0x1b
+#define MODEMASK	0x1f
+#define NOINT		0xc0
+	
+#define MCLK	(72000000)
+	
+/* Vectored Interrupt Controller (VIC) */
+#define VIC_BASE_ADDR	0xFFFFF000
+#define VICIRQStatus   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x000))
+#define VICFIQStatus   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x004))
+#define VICRawIntr     (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x008))
+#define VICIntSelect   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x00C))
+#define VICIntEnable   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x010))
+#define VICIntEnClr    (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x014))
+#define VICSoftInt     (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x018))
+#define VICSoftIntClr  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x01C))
+#define VICProtection  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x020))
+#define VICSWPrioMask  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x024))
+
+#define VICVectAddr0   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x100))
+#define VICVectAddr1   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x104))
+#define VICVectAddr2   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x108))
+#define VICVectAddr3   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x10C))
+#define VICVectAddr4   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x110))
+#define VICVectAddr5   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x114))
+#define VICVectAddr6   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x118))
+#define VICVectAddr7   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x11C))
+#define VICVectAddr8   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x120))
+#define VICVectAddr9   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x124))
+#define VICVectAddr10  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x128))
+#define VICVectAddr11  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x12C))
+#define VICVectAddr12  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x130))
+#define VICVectAddr13  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x134))
+#define VICVectAddr14  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x138))
+#define VICVectAddr15  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x13C))
+#define VICVectAddr16  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x140))
+#define VICVectAddr17  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x144))
+#define VICVectAddr18  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x148))
+#define VICVectAddr19  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x14C))
+#define VICVectAddr20  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x150))
+#define VICVectAddr21  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x154))
+#define VICVectAddr22  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x158))
+#define VICVectAddr23  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x15C))
+#define VICVectAddr24  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x160))
+#define VICVectAddr25  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x164))
+#define VICVectAddr26  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x168))
+#define VICVectAddr27  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x16C))
+#define VICVectAddr28  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x170))
+#define VICVectAddr29  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x174))
+#define VICVectAddr30  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x178))
+#define VICVectAddr31  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x17C))
+
+/* The name convention below is from previous LPC2000 family MCUs, in LPC23xx/24xx,
+these registers are known as "VICVectPriority(x)". */
+#define VICVectCntl0   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x200))
+#define VICVectCntl1   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x204))
+#define VICVectCntl2   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x208))
+#define VICVectCntl3   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x20C))
+#define VICVectCntl4   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x210))
+#define VICVectCntl5   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x214))
+#define VICVectCntl6   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x218))
+#define VICVectCntl7   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x21C))
+#define VICVectCntl8   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x220))
+#define VICVectCntl9   (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x224))
+#define VICVectCntl10  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x228))
+#define VICVectCntl11  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x22C))
+#define VICVectCntl12  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x230))
+#define VICVectCntl13  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x234))
+#define VICVectCntl14  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x238))
+#define VICVectCntl15  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x23C))
+#define VICVectCntl16  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x240))
+#define VICVectCntl17  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x244))
+#define VICVectCntl18  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x248))
+#define VICVectCntl19  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x24C))
+#define VICVectCntl20  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x250))
+#define VICVectCntl21  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x254))
+#define VICVectCntl22  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x258))
+#define VICVectCntl23  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x25C))
+#define VICVectCntl24  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x260))
+#define VICVectCntl25  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x264))
+#define VICVectCntl26  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x268))
+#define VICVectCntl27  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x26C))
+#define VICVectCntl28  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x270))
+#define VICVectCntl29  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x274))
+#define VICVectCntl30  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x278))
+#define VICVectCntl31  (*(volatile unsigned long *)(VIC_BASE_ADDR + 0x27C))
+
+#define VICVectAddr    (*(volatile unsigned long *)(VIC_BASE_ADDR + 0xF00))
+
+
+/* Pin Connect Block */
+#define PINSEL_BASE_ADDR	0xE002C000
+#define PINSEL0        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x00))
+#define PINSEL1        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x04))
+#define PINSEL2        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x08))
+#define PINSEL3        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x0C))
+#define PINSEL4        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x10))
+#define PINSEL5        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x14))
+#define PINSEL6        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x18))
+#define PINSEL7        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x1C))
+#define PINSEL8        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x20))
+#define PINSEL9        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x24))
+#define PINSEL10       (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x28))
+#define PINSEL11       (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x2C))
+
+#define PINMODE0        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x40))
+#define PINMODE1        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x44))
+#define PINMODE2        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x48))
+#define PINMODE3        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x4C))
+#define PINMODE4        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x50))
+#define PINMODE5        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x54))
+#define PINMODE6        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x58))
+#define PINMODE7        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x5C))
+#define PINMODE8        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x60))
+#define PINMODE9        (*(volatile unsigned long *)(PINSEL_BASE_ADDR + 0x64))
+
+/* General Purpose Input/Output (GPIO) */
+#define GPIO_BASE_ADDR		0xE0028000
+#define IOPIN0         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x00))
+#define IOSET0         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x04))
+#define IODIR0         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x08))
+#define IOCLR0         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x0C))
+#define IOPIN1         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x10))
+#define IOSET1         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x14))
+#define IODIR1         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x18))
+#define IOCLR1         (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x1C))
+
+/* GPIO Interrupt Registers */
+#define IO0_INT_EN_R    (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x90)) 
+#define IO0_INT_EN_F    (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x94))
+#define IO0_INT_STAT_R  (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x84))
+#define IO0_INT_STAT_F  (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x88))
+#define IO0_INT_CLR     (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x8C))
+
+#define IO2_INT_EN_R    (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xB0)) 
+#define IO2_INT_EN_F    (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xB4))
+#define IO2_INT_STAT_R  (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xA4))
+#define IO2_INT_STAT_F  (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xA8))
+#define IO2_INT_CLR     (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0xAC))
+
+#define IO_INT_STAT     (*(volatile unsigned long *)(GPIO_BASE_ADDR + 0x80))
+
+#define PARTCFG_BASE_ADDR		0x3FFF8000
+#define PARTCFG        (*(volatile unsigned long *)(PARTCFG_BASE_ADDR + 0x00)) 
+
+/* Fast I/O setup */
+#define FIO_BASE_ADDR		0x3FFFC000
+#define FIO0DIR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x00)) 
+#define FIO0MASK       (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x10))
+#define FIO0PIN        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x14))
+#define FIO0SET        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x18))
+#define FIO0CLR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x1C))
+
+#define FIO1DIR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x20)) 
+#define FIO1MASK       (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x30))
+#define FIO1PIN        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x34))
+#define FIO1SET        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x38))
+#define FIO1CLR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x3C))
+
+#define FIO2DIR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x40)) 
+#define FIO2MASK       (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x50))
+#define FIO2PIN        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x54))
+#define FIO2SET        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x58))
+#define FIO2CLR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x5C))
+
+#define FIO3DIR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x60)) 
+#define FIO3MASK       (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x70))
+#define FIO3PIN        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x74))
+#define FIO3SET        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x78))
+#define FIO3CLR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x7C))
+
+#define FIO4DIR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x80)) 
+#define FIO4MASK       (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x90))
+#define FIO4PIN        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x94))
+#define FIO4SET        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x98))
+#define FIO4CLR        (*(volatile unsigned long *)(FIO_BASE_ADDR + 0x9C))
+
+/* FIOs can be accessed through WORD, HALF-WORD or BYTE. */
+#define FIO0DIR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x00)) 
+#define FIO1DIR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x20)) 
+#define FIO2DIR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x40)) 
+#define FIO3DIR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x60)) 
+#define FIO4DIR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x80)) 
+
+#define FIO0DIR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x01)) 
+#define FIO1DIR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x21)) 
+#define FIO2DIR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x41)) 
+#define FIO3DIR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x61)) 
+#define FIO4DIR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x81)) 
+
+#define FIO0DIR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x02)) 
+#define FIO1DIR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x22)) 
+#define FIO2DIR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x42)) 
+#define FIO3DIR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x62)) 
+#define FIO4DIR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x82)) 
+
+#define FIO0DIR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x03)) 
+#define FIO1DIR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x23)) 
+#define FIO2DIR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x43)) 
+#define FIO3DIR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x63)) 
+#define FIO4DIR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x83)) 
+
+#define FIO0DIRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x00)) 
+#define FIO1DIRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x20)) 
+#define FIO2DIRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x40)) 
+#define FIO3DIRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x60)) 
+#define FIO4DIRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x80)) 
+
+#define FIO0DIRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x02)) 
+#define FIO1DIRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x22)) 
+#define FIO2DIRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x42)) 
+#define FIO3DIRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x62)) 
+#define FIO4DIRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x82)) 
+
+#define FIO0MASK0      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x10)) 
+#define FIO1MASK0      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x30)) 
+#define FIO2MASK0      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x50)) 
+#define FIO3MASK0      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x70)) 
+#define FIO4MASK0      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x90)) 
+
+#define FIO0MASK1      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x11)) 
+#define FIO1MASK1      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x21)) 
+#define FIO2MASK1      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x51)) 
+#define FIO3MASK1      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x71)) 
+#define FIO4MASK1      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x91)) 
+
+#define FIO0MASK2      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x12)) 
+#define FIO1MASK2      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x32)) 
+#define FIO2MASK2      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x52)) 
+#define FIO3MASK2      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x72)) 
+#define FIO4MASK2      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x92)) 
+
+#define FIO0MASK3      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x13)) 
+#define FIO1MASK3      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x33)) 
+#define FIO2MASK3      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x53)) 
+#define FIO3MASK3      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x73)) 
+#define FIO4MASK3      (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x93)) 
+
+#define FIO0MASKL      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x10)) 
+#define FIO1MASKL      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x30)) 
+#define FIO2MASKL      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x50)) 
+#define FIO3MASKL      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x70)) 
+#define FIO4MASKL      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x90)) 
+
+#define FIO0MASKU      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x12)) 
+#define FIO1MASKU      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x32)) 
+#define FIO2MASKU      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x52)) 
+#define FIO3MASKU      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x72)) 
+#define FIO4MASKU      (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x92)) 
+
+#define FIO0PIN0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x14)) 
+#define FIO1PIN0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x34)) 
+#define FIO2PIN0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x54)) 
+#define FIO3PIN0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x74)) 
+#define FIO4PIN0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x94)) 
+
+#define FIO0PIN1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x15)) 
+#define FIO1PIN1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x35)) 
+#define FIO2PIN1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x55)) 
+#define FIO3PIN1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x75)) 
+#define FIO4PIN1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x95)) 
+
+#define FIO0PIN2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x16)) 
+#define FIO1PIN2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x36)) 
+#define FIO2PIN2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x56)) 
+#define FIO3PIN2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x76)) 
+#define FIO4PIN2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x96)) 
+
+#define FIO0PIN3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x17)) 
+#define FIO1PIN3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x37)) 
+#define FIO2PIN3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x57)) 
+#define FIO3PIN3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x77)) 
+#define FIO4PIN3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x97)) 
+
+#define FIO0PINL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x14)) 
+#define FIO1PINL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x34)) 
+#define FIO2PINL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x54)) 
+#define FIO3PINL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x74)) 
+#define FIO4PINL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x94)) 
+
+#define FIO0PINU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x16)) 
+#define FIO1PINU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x36)) 
+#define FIO2PINU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x56)) 
+#define FIO3PINU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x76)) 
+#define FIO4PINU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x96)) 
+
+#define FIO0SET0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x18)) 
+#define FIO1SET0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x38)) 
+#define FIO2SET0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x58)) 
+#define FIO3SET0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x78)) 
+#define FIO4SET0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x98)) 
+
+#define FIO0SET1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x19)) 
+#define FIO1SET1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x29)) 
+#define FIO2SET1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x59)) 
+#define FIO3SET1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x79)) 
+#define FIO4SET1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x99)) 
+
+#define FIO0SET2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1A)) 
+#define FIO1SET2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3A)) 
+#define FIO2SET2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5A)) 
+#define FIO3SET2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7A)) 
+#define FIO4SET2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9A)) 
+
+#define FIO0SET3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1B)) 
+#define FIO1SET3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3B)) 
+#define FIO2SET3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5B)) 
+#define FIO3SET3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7B)) 
+#define FIO4SET3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9B)) 
+
+#define FIO0SETL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x18)) 
+#define FIO1SETL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x38)) 
+#define FIO2SETL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x58)) 
+#define FIO3SETL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x78)) 
+#define FIO4SETL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x98)) 
+
+#define FIO0SETU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1A)) 
+#define FIO1SETU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3A)) 
+#define FIO2SETU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5A)) 
+#define FIO3SETU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7A)) 
+#define FIO4SETU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9A)) 
+
+#define FIO0CLR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1C)) 
+#define FIO1CLR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3C)) 
+#define FIO2CLR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5C)) 
+#define FIO3CLR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7C)) 
+#define FIO4CLR0       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9C)) 
+
+#define FIO0CLR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1D)) 
+#define FIO1CLR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x2D)) 
+#define FIO2CLR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5D)) 
+#define FIO3CLR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7D)) 
+#define FIO4CLR1       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9D)) 
+
+#define FIO0CLR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1E)) 
+#define FIO1CLR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3E)) 
+#define FIO2CLR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5E)) 
+#define FIO3CLR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7E)) 
+#define FIO4CLR2       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9E)) 
+
+#define FIO0CLR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x1F)) 
+#define FIO1CLR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x3F)) 
+#define FIO2CLR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x5F)) 
+#define FIO3CLR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x7F)) 
+#define FIO4CLR3       (*(volatile unsigned char *)(FIO_BASE_ADDR + 0x9F)) 
+
+#define FIO0CLRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1C)) 
+#define FIO1CLRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3C)) 
+#define FIO2CLRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5C)) 
+#define FIO3CLRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7C)) 
+#define FIO4CLRL       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9C)) 
+
+#define FIO0CLRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x1E)) 
+#define FIO1CLRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x3E)) 
+#define FIO2CLRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x5E)) 
+#define FIO3CLRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x7E)) 
+#define FIO4CLRU       (*(volatile unsigned short *)(FIO_BASE_ADDR + 0x9E)) 
+
+
+/* System Control Block(SCB) modules include Memory Accelerator Module,
+Phase Locked Loop, VPB divider, Power Control, External Interrupt, 
+Reset, and Code Security/Debugging */
+#define SCB_BASE_ADDR	0xE01FC000
+
+/* Memory Accelerator Module (MAM) */
+#define MAMCR          (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x000))
+#define MAMTIM         (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x004))
+#define MEMMAP         (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x040))
+
+/* Phase Locked Loop (PLL) */
+#define PLLCON         (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x080))
+#define PLLCFG         (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x084))
+#define PLLSTAT        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x088))
+#define PLLFEED        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x08C))
+
+/* Power Control */
+#define PCON           (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x0C0))
+#define PCONP          (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x0C4))
+
+/* Clock Divider */
+#define CCLKCFG        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x104))
+#define USBCLKCFG      (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x108))
+#define CLKSRCSEL      (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x10C))
+#define PCLKSEL0       (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1A8))
+#define PCLKSEL1       (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1AC))
+	
+/* External Interrupts */
+#define EXTINT         (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x140))
+#define INTWAKE        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x144))
+#define EXTMODE        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x148))
+#define EXTPOLAR       (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x14C))
+
+/* Reset, reset source identification */
+#define RSIR           (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x180))
+
+/* RSID, code security protection */
+#define CSPR           (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x184))
+
+/* AHB configuration */
+#define AHBCFG1        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x188))
+#define AHBCFG2        (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x18C))
+
+/* System Controls and Status */
+#define SCS            (*(volatile unsigned long *)(SCB_BASE_ADDR + 0x1A0))	
+
+/* MPMC(EMC) registers, note: all the external memory controller(EMC) registers 
+are for LPC24xx only. */
+#define STATIC_MEM0_BASE		0x80000000
+#define STATIC_MEM1_BASE		0x81000000
+#define STATIC_MEM2_BASE		0x82000000
+#define STATIC_MEM3_BASE		0x83000000
+
+#define DYNAMIC_MEM0_BASE		0xA0000000
+#define DYNAMIC_MEM1_BASE		0xB0000000
+#define DYNAMIC_MEM2_BASE		0xC0000000
+#define DYNAMIC_MEM3_BASE		0xD0000000
+
+/* External Memory Controller (EMC) */
+#define EMC_BASE_ADDR		0xFFE08000
+#define EMC_CTRL       (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x000))
+#define EMC_STAT       (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x004))
+#define EMC_CONFIG     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x008))
+
+/* Dynamic RAM access registers */
+#define EMC_DYN_CTRL     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x020))
+#define EMC_DYN_RFSH     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x024))
+#define EMC_DYN_RD_CFG   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x028))
+#define EMC_DYN_RP       (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x030))
+#define EMC_DYN_RAS      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x034))
+#define EMC_DYN_SREX     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x038))
+#define EMC_DYN_APR      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x03C))
+#define EMC_DYN_DAL      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x040))
+#define EMC_DYN_WR       (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x044))
+#define EMC_DYN_RC       (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x048))
+#define EMC_DYN_RFC      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x04C))
+#define EMC_DYN_XSR      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x050))
+#define EMC_DYN_RRD      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x054))
+#define EMC_DYN_MRD      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x058))
+
+#define EMC_DYN_CFG0     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x100))
+#define EMC_DYN_RASCAS0  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x104))
+#define EMC_DYN_CFG1     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x140))
+#define EMC_DYN_RASCAS1  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x144))
+#define EMC_DYN_CFG2     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x160))
+#define EMC_DYN_RASCAS2  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x164))
+#define EMC_DYN_CFG3     (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x180))
+#define EMC_DYN_RASCAS3  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x184))
+
+/* static RAM access registers */
+#define EMC_STA_CFG0      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x200))
+#define EMC_STA_WAITWEN0  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x204))
+#define EMC_STA_WAITOEN0  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x208))
+#define EMC_STA_WAITRD0   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x20C))
+#define EMC_STA_WAITPAGE0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x210))
+#define EMC_STA_WAITWR0   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x214))
+#define EMC_STA_WAITTURN0 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x218))
+
+#define EMC_STA_CFG1      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x220))
+#define EMC_STA_WAITWEN1  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x224))
+#define EMC_STA_WAITOEN1  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x228))
+#define EMC_STA_WAITRD1   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x22C))
+#define EMC_STA_WAITPAGE1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x230))
+#define EMC_STA_WAITWR1   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x234))
+#define EMC_STA_WAITTURN1 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x238))
+
+#define EMC_STA_CFG2      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x240))
+#define EMC_STA_WAITWEN2  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x244))
+#define EMC_STA_WAITOEN2  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x248))
+#define EMC_STA_WAITRD2   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x24C))
+#define EMC_STA_WAITPAGE2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x250))
+#define EMC_STA_WAITWR2   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x254))
+#define EMC_STA_WAITTURN2 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x258))
+
+#define EMC_STA_CFG3      (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x260))
+#define EMC_STA_WAITWEN3  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x264))
+#define EMC_STA_WAITOEN3  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x268))
+#define EMC_STA_WAITRD3   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x26C))
+#define EMC_STA_WAITPAGE3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x270))
+#define EMC_STA_WAITWR3   (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x274))
+#define EMC_STA_WAITTURN3 (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x278))
+
+#define EMC_STA_EXT_WAIT  (*(volatile unsigned long *)(EMC_BASE_ADDR + 0x880))
+
+	
+/* Timer 0 */
+#define TMR0_BASE_ADDR		0xE0004000
+#define T0IR           (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x00))
+#define T0TCR          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x04))
+#define T0TC           (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x08))
+#define T0PR           (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x0C))
+#define T0PC           (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x10))
+#define T0MCR          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x14))
+#define T0MR0          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x18))
+#define T0MR1          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x1C))
+#define T0MR2          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x20))
+#define T0MR3          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x24))
+#define T0CCR          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x28))
+#define T0CR0          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x2C))
+#define T0CR1          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x30))
+#define T0CR2          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x34))
+#define T0CR3          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x38))
+#define T0EMR          (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x3C))
+#define T0CTCR         (*(volatile unsigned long *)(TMR0_BASE_ADDR + 0x70))
+
+/* Timer 1 */
+#define TMR1_BASE_ADDR		0xE0008000
+#define T1IR           (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x00))
+#define T1TCR          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x04))
+#define T1TC           (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x08))
+#define T1PR           (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x0C))
+#define T1PC           (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x10))
+#define T1MCR          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x14))
+#define T1MR0          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x18))
+#define T1MR1          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x1C))
+#define T1MR2          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x20))
+#define T1MR3          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x24))
+#define T1CCR          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x28))
+#define T1CR0          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x2C))
+#define T1CR1          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x30))
+#define T1CR2          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x34))
+#define T1CR3          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x38))
+#define T1EMR          (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x3C))
+#define T1CTCR         (*(volatile unsigned long *)(TMR1_BASE_ADDR + 0x70))
+
+/* Timer 2 */
+#define TMR2_BASE_ADDR		0xE0070000
+#define T2IR           (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x00))
+#define T2TCR          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x04))
+#define T2TC           (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x08))
+#define T2PR           (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x0C))
+#define T2PC           (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x10))
+#define T2MCR          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x14))
+#define T2MR0          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x18))
+#define T2MR1          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x1C))
+#define T2MR2          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x20))
+#define T2MR3          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x24))
+#define T2CCR          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x28))
+#define T2CR0          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x2C))
+#define T2CR1          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x30))
+#define T2CR2          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x34))
+#define T2CR3          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x38))
+#define T2EMR          (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x3C))
+#define T2CTCR         (*(volatile unsigned long *)(TMR2_BASE_ADDR + 0x70))
+
+/* Timer 3 */
+#define TMR3_BASE_ADDR		0xE0074000
+#define T3IR           (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x00))
+#define T3TCR          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x04))
+#define T3TC           (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x08))
+#define T3PR           (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x0C))
+#define T3PC           (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x10))
+#define T3MCR          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x14))
+#define T3MR0          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x18))
+#define T3MR1          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x1C))
+#define T3MR2          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x20))
+#define T3MR3          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x24))
+#define T3CCR          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x28))
+#define T3CR0          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x2C))
+#define T3CR1          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x30))
+#define T3CR2          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x34))
+#define T3CR3          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x38))
+#define T3EMR          (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x3C))
+#define T3CTCR         (*(volatile unsigned long *)(TMR3_BASE_ADDR + 0x70))
+
+
+/* Pulse Width Modulator (PWM) */
+#define PWM0_BASE_ADDR		0xE0014000
+#define PWM0IR          (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x00))
+#define PWM0TCR         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x04))
+#define PWM0TC          (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x08))
+#define PWM0PR          (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x0C))
+#define PWM0PC          (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x10))
+#define PWM0MCR         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x14))
+#define PWM0MR0         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x18))
+#define PWM0MR1         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x1C))
+#define PWM0MR2         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x20))
+#define PWM0MR3         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x24))
+#define PWM0CCR         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x28))
+#define PWM0CR0         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x2C))
+#define PWM0CR1         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x30))
+#define PWM0CR2         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x34))
+#define PWM0CR3         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x38))
+#define PWM0EMR         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x3C))
+#define PWM0MR4         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x40))
+#define PWM0MR5         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x44))
+#define PWM0MR6         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x48))
+#define PWM0PCR         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x4C))
+#define PWM0LER         (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x50))
+#define PWM0CTCR        (*(volatile unsigned long *)(PWM0_BASE_ADDR + 0x70))
+
+#define PWM1_BASE_ADDR		0xE0018000
+#define PWM1IR          (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x00))
+#define PWM1TCR         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x04))
+#define PWM1TC          (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x08))
+#define PWM1PR          (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x0C))
+#define PWM1PC          (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x10))
+#define PWM1MCR         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x14))
+#define PWM1MR0         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x18))
+#define PWM1MR1         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x1C))
+#define PWM1MR2         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x20))
+#define PWM1MR3         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x24))
+#define PWM1CCR         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x28))
+#define PWM1CR0         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x2C))
+#define PWM1CR1         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x30))
+#define PWM1CR2         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x34))
+#define PWM1CR3         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x38))
+#define PWM1EMR         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x3C))
+#define PWM1MR4         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x40))
+#define PWM1MR5         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x44))
+#define PWM1MR6         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x48))
+#define PWM1PCR         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x4C))
+#define PWM1LER         (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x50))
+#define PWM1CTCR        (*(volatile unsigned long *)(PWM1_BASE_ADDR + 0x70))
+
+
+/* Universal Asynchronous Receiver Transmitter 0 (UART0) */
+#define UART0_BASE_ADDR		0xE000C000
+#define U0RBR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0THR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0DLL          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x00))
+#define U0DLM          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x04))
+#define U0IER          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x04))
+#define U0IIR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x08))
+#define U0FCR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x08))
+#define U0LCR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x0C))
+#define U0LSR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x14))
+#define U0SCR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x1C))
+#define U0ACR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x20))
+#define U0ICR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x24))
+#define U0FDR          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x28))
+#define U0TER          (*(volatile unsigned long *)(UART0_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 1 (UART1) */
+#define UART1_BASE_ADDR		0xE0010000
+#define U1RBR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1THR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1DLL          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x00))
+#define U1DLM          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x04))
+#define U1IER          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x04))
+#define U1IIR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x08))
+#define U1FCR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x08))
+#define U1LCR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x0C))
+#define U1MCR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x10))
+#define U1LSR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x14))
+#define U1MSR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x18))
+#define U1SCR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x1C))
+#define U1ACR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x20))
+#define U1FDR          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x28))
+#define U1TER          (*(volatile unsigned long *)(UART1_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 2 (UART2) */
+#define UART2_BASE_ADDR		0xE0078000
+#define U2RBR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2THR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2DLL          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x00))
+#define U2DLM          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x04))
+#define U2IER          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x04))
+#define U2IIR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x08))
+#define U2FCR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x08))
+#define U2LCR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x0C))
+#define U2LSR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x14))
+#define U2SCR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x1C))
+#define U2ACR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x20))
+#define U2ICR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x24))
+#define U2FDR          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x28))
+#define U2TER          (*(volatile unsigned long *)(UART2_BASE_ADDR + 0x30))
+
+/* Universal Asynchronous Receiver Transmitter 3 (UART3) */
+#define UART3_BASE_ADDR		0xE007C000
+#define U3RBR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3THR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3DLL          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x00))
+#define U3DLM          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x04))
+#define U3IER          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x04))
+#define U3IIR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x08))
+#define U3FCR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x08))
+#define U3LCR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x0C))
+#define U3LSR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x14))
+#define U3SCR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x1C))
+#define U3ACR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x20))
+#define U3ICR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x24))
+#define U3FDR          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x28))
+#define U3TER          (*(volatile unsigned long *)(UART3_BASE_ADDR + 0x30))
+
+/* I2C Interface 0 */
+#define I2C0_BASE_ADDR		0xE001C000
+#define I20CONSET      (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x00))
+#define I20STAT        (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x04))
+#define I20DAT         (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x08))
+#define I20ADR         (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x0C))
+#define I20SCLH        (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x10))
+#define I20SCLL        (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x14))
+#define I20CONCLR      (*(volatile unsigned long *)(I2C0_BASE_ADDR + 0x18))
+
+/* I2C Interface 1 */
+#define I2C1_BASE_ADDR		0xE005C000
+#define I21CONSET      (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x00))
+#define I21STAT        (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x04))
+#define I21DAT         (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x08))
+#define I21ADR         (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x0C))
+#define I21SCLH        (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x10))
+#define I21SCLL        (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x14))
+#define I21CONCLR      (*(volatile unsigned long *)(I2C1_BASE_ADDR + 0x18))
+
+/* I2C Interface 2 */
+#define I2C2_BASE_ADDR		0xE0080000
+#define I22CONSET      (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x00))
+#define I22STAT        (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x04))
+#define I22DAT         (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x08))
+#define I22ADR         (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x0C))
+#define I22SCLH        (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x10))
+#define I22SCLL        (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x14))
+#define I22CONCLR      (*(volatile unsigned long *)(I2C2_BASE_ADDR + 0x18))
+
+/* SPI0 (Serial Peripheral Interface 0) */
+#define SPI0_BASE_ADDR		0xE0020000
+#define S0SPCR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x00))
+#define S0SPSR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x04))
+#define S0SPDR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x08))
+#define S0SPCCR        (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x0C))
+#define S0SPINT        (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x1C))
+
+/* SSP0 Controller */
+#define SSP0_BASE_ADDR		0xE0068000
+#define SSP0CR0        (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x00))
+#define SSP0CR1        (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x04))
+#define SSP0DR         (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x08))
+#define SSP0SR         (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x0C))
+#define SSP0CPSR       (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x10))
+#define SSP0IMSC       (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x14))
+#define SSP0RIS        (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x18))
+#define SSP0MIS        (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x1C))
+#define SSP0ICR        (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x20))
+#define SSP0DMACR      (*(volatile unsigned long *)(SSP0_BASE_ADDR + 0x24))
+
+/* SSP1 Controller */
+#define SSP1_BASE_ADDR		0xE0030000
+#define SSP1CR0        (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x00))
+#define SSP1CR1        (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x04))
+#define SSP1DR         (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x08))
+#define SSP1SR         (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x0C))
+#define SSP1CPSR       (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x10))
+#define SSP1IMSC       (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x14))
+#define SSP1RIS        (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x18))
+#define SSP1MIS        (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x1C))
+#define SSP1ICR        (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x20))
+#define SSP1DMACR      (*(volatile unsigned long *)(SSP1_BASE_ADDR + 0x24))
+
+
+/* Real Time Clock */
+#define RTC_BASE_ADDR		0xE0024000
+#define RTC_ILR         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x00))
+#define RTC_CTC         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x04))
+#define RTC_CCR         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x08))
+#define RTC_CIIR        (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x0C))
+#define RTC_AMR         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x10))
+#define RTC_CTIME0      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x14))
+#define RTC_CTIME1      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x18))
+#define RTC_CTIME2      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x1C))
+#define RTC_SEC         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x20))
+#define RTC_MIN         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x24))
+#define RTC_HOUR        (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x28))
+#define RTC_DOM         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x2C))
+#define RTC_DOW         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x30))
+#define RTC_DOY         (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x34))
+#define RTC_MONTH       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x38))
+#define RTC_YEAR        (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x3C))
+#define RTC_CISS        (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x40))
+#define RTC_ALSEC       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x60))
+#define RTC_ALMIN       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x64))
+#define RTC_ALHOUR      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x68))
+#define RTC_ALDOM       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x6C))
+#define RTC_ALDOW       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x70))
+#define RTC_ALDOY       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x74))
+#define RTC_ALMON       (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x78))
+#define RTC_ALYEAR      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x7C))
+#define RTC_PREINT      (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x80))
+#define RTC_PREFRAC     (*(volatile unsigned long *)(RTC_BASE_ADDR + 0x84))
+
+
+/* A/D Converter 0 (AD0) */
+#define AD0_BASE_ADDR		0xE0034000
+#define AD0CR          (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x00))
+#define AD0GDR         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x04))
+#define AD0INTEN       (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x0C))
+#define AD0DR0         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x10))
+#define AD0DR1         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x14))
+#define AD0DR2         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x18))
+#define AD0DR3         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x1C))
+#define AD0DR4         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x20))
+#define AD0DR5         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x24))
+#define AD0DR6         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x28))
+#define AD0DR7         (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x2C))
+#define AD0STAT        (*(volatile unsigned long *)(AD0_BASE_ADDR + 0x30))
+
+
+/* D/A Converter */
+#define DAC_BASE_ADDR		0xE006C000
+#define DACR           (*(volatile unsigned long *)(DAC_BASE_ADDR + 0x00))
+
+
+/* Watchdog */
+#define WDG_BASE_ADDR		0xE0000000
+#define WDMOD          (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x00))
+#define WDTC           (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x04))
+#define WDFEED         (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x08))
+#define WDTV           (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x0C))
+#define WDCLKSEL       (*(volatile unsigned long *)(WDG_BASE_ADDR + 0x10))
+
+/* CAN CONTROLLERS AND ACCEPTANCE FILTER */
+#define CAN_ACCEPT_BASE_ADDR		0xE003C000
+#define CAN_AFMR		(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x00))  	
+#define CAN_SFF_SA 		(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x04))  	
+#define CAN_SFF_GRP_SA 	(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x08))
+#define CAN_EFF_SA 		(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x0C))
+#define CAN_EFF_GRP_SA 	(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x10))  	
+#define CAN_EOT 		(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x14))
+#define CAN_LUT_ERR_ADR (*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x18))  	
+#define CAN_LUT_ERR 	(*(volatile unsigned long *)(CAN_ACCEPT_BASE_ADDR + 0x1C))
+
+#define CAN_CENTRAL_BASE_ADDR		0xE0040000  	
+#define CAN_TX_SR 	(*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x00))  	
+#define CAN_RX_SR 	(*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x04))  	
+#define CAN_MSR 	(*(volatile unsigned long *)(CAN_CENTRAL_BASE_ADDR + 0x08))
+
+#define CAN1_BASE_ADDR		0xE0044000
+#define CAN1MOD 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x00))  	
+#define CAN1CMR 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x04))  	
+#define CAN1GSR 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x08))  	
+#define CAN1ICR 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x0C))  	
+#define CAN1IER 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x10))
+#define CAN1BTR 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x14))  	
+#define CAN1EWL 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x18))  	
+#define CAN1SR 		(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x1C))  	
+#define CAN1RFS 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x20))  	
+#define CAN1RID 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x24))
+#define CAN1RDA 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x28))  	
+#define CAN1RDB 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x2C))
+  	
+#define CAN1TFI1 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x30))  	
+#define CAN1TID1 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x34))  	
+#define CAN1TDA1 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x38))
+#define CAN1TDB1 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x3C))  	
+#define CAN1TFI2 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x40))  	
+#define CAN1TID2 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x44))  	
+#define CAN1TDA2 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x48))  	
+#define CAN1TDB2 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x4C))
+#define CAN1TFI3 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x50))  	
+#define CAN1TID3 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x54))  	
+#define CAN1TDA3 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x58))  	
+#define CAN1TDB3 	(*(volatile unsigned long *)(CAN1_BASE_ADDR + 0x5C))
+
+#define CAN2_BASE_ADDR		0xE0048000
+#define CAN2MOD 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x00))  	
+#define CAN2CMR 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x04))  	
+#define CAN2GSR 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x08))  	
+#define CAN2ICR 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x0C))  	
+#define CAN2IER 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x10))
+#define CAN2BTR 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x14))  	
+#define CAN2EWL 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x18))  	
+#define CAN2SR 		(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x1C))  	
+#define CAN2RFS 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x20))  	
+#define CAN2RID 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x24))
+#define CAN2RDA 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x28))  	
+#define CAN2RDB 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x2C))
+  	
+#define CAN2TFI1 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x30))  	
+#define CAN2TID1 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x34))  	
+#define CAN2TDA1 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x38))
+#define CAN2TDB1 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x3C))  	
+#define CAN2TFI2 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x40))  	
+#define CAN2TID2 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x44))  	
+#define CAN2TDA2 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x48))  	
+#define CAN2TDB2 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x4C))
+#define CAN2TFI3 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x50))  	
+#define CAN2TID3 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x54))  	
+#define CAN2TDA3 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x58))  	
+#define CAN2TDB3 	(*(volatile unsigned long *)(CAN2_BASE_ADDR + 0x5C))
+
+
+/* MultiMedia Card Interface(MCI) Controller */
+#define MCI_BASE_ADDR		0xE008C000
+#define MCI_POWER      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x00))
+#define MCI_CLOCK      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x04))
+#define MCI_ARGUMENT   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x08))
+#define MCI_COMMAND    (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x0C))
+#define MCI_RESP_CMD   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x10))
+#define MCI_RESP0      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x14))
+#define MCI_RESP1      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x18))
+#define MCI_RESP2      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x1C))
+#define MCI_RESP3      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x20))
+#define MCI_DATA_TMR   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x24))
+#define MCI_DATA_LEN   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x28))
+#define MCI_DATA_CTRL  (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x2C))
+#define MCI_DATA_CNT   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x30))
+#define MCI_STATUS     (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x34))
+#define MCI_CLEAR      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x38))
+#define MCI_MASK0      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x3C))
+#define MCI_MASK1      (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x40))
+#define MCI_FIFO_CNT   (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x48))
+#define MCI_FIFO       (*(volatile unsigned long *)(MCI_BASE_ADDR + 0x80))
+
+
+/* I2S Interface Controller (I2S) */
+#define I2S_BASE_ADDR		0xE0088000
+#define I2S_DAO        (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x00))
+#define I2S_DAI        (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x04))
+#define I2S_TX_FIFO    (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x08))
+#define I2S_RX_FIFO    (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x0C))
+#define I2S_STATE      (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x10))
+#define I2S_DMA1       (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x14))
+#define I2S_DMA2       (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x18))
+#define I2S_IRQ        (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x1C))
+#define I2S_TXRATE     (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x20))
+#define I2S_RXRATE     (*(volatile unsigned long *)(I2S_BASE_ADDR + 0x24))
+
+
+/* General-purpose DMA Controller */
+#define DMA_BASE_ADDR		0xFFE04000
+#define GPDMA_INT_STAT         (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x000))
+#define GPDMA_INT_TCSTAT       (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x004))
+#define GPDMA_INT_TCCLR        (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x008))
+#define GPDMA_INT_ERR_STAT     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x00C))
+#define GPDMA_INT_ERR_CLR      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x010))
+#define GPDMA_RAW_INT_TCSTAT   (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x014))
+#define GPDMA_RAW_INT_ERR_STAT (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x018))
+#define GPDMA_ENABLED_CHNS     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x01C))
+#define GPDMA_SOFT_BREQ        (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x020))
+#define GPDMA_SOFT_SREQ        (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x024))
+#define GPDMA_SOFT_LBREQ       (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x028))
+#define GPDMA_SOFT_LSREQ       (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x02C))
+#define GPDMA_CONFIG           (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x030))
+#define GPDMA_SYNC             (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x034))
+
+/* DMA channel 0 registers */
+#define GPDMA_CH0_SRC      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x100))
+#define GPDMA_CH0_DEST     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x104))
+#define GPDMA_CH0_LLI      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x108))
+#define GPDMA_CH0_CTRL     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x10C))
+#define GPDMA_CH0_CFG      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x110))
+
+/* DMA channel 1 registers */
+#define GPDMA_CH1_SRC      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x120))
+#define GPDMA_CH1_DEST     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x124))
+#define GPDMA_CH1_LLI      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x128))
+#define GPDMA_CH1_CTRL     (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x12C))
+#define GPDMA_CH1_CFG      (*(volatile unsigned long *)(DMA_BASE_ADDR + 0x130))
+
+
+/* USB Controller */
+#define USB_INT_BASE_ADDR	0xE01FC1C0
+#define USB_BASE_ADDR		0xFFE0C200		/* USB Base Address */
+
+#define USB_INT_STAT    (*(volatile unsigned long *)(USB_INT_BASE_ADDR + 0x00))
+
+/* USB Device Interrupt Registers */
+#define DEV_INT_STAT    (*(volatile unsigned long *)(USB_BASE_ADDR + 0x00))
+#define DEV_INT_EN      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x04))
+#define DEV_INT_CLR     (*(volatile unsigned long *)(USB_BASE_ADDR + 0x08))
+#define DEV_INT_SET     (*(volatile unsigned long *)(USB_BASE_ADDR + 0x0C))
+#define DEV_INT_PRIO    (*(volatile unsigned long *)(USB_BASE_ADDR + 0x2C))
+
+/* USB Device Endpoint Interrupt Registers */
+#define EP_INT_STAT     (*(volatile unsigned long *)(USB_BASE_ADDR + 0x30))
+#define EP_INT_EN       (*(volatile unsigned long *)(USB_BASE_ADDR + 0x34))
+#define EP_INT_CLR      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x38))
+#define EP_INT_SET      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x3C))
+#define EP_INT_PRIO     (*(volatile unsigned long *)(USB_BASE_ADDR + 0x40))
+
+/* USB Device Endpoint Realization Registers */
+#define REALIZE_EP      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x44))
+#define EP_INDEX        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x48))
+#define MAXPACKET_SIZE  (*(volatile unsigned long *)(USB_BASE_ADDR + 0x4C))
+
+/* USB Device Command Reagisters */
+#define CMD_CODE        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x10))
+#define CMD_DATA        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x14))
+
+/* USB Device Data Transfer Registers */
+#define RX_DATA         (*(volatile unsigned long *)(USB_BASE_ADDR + 0x18))
+#define TX_DATA         (*(volatile unsigned long *)(USB_BASE_ADDR + 0x1C))
+#define RX_PLENGTH      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x20))
+#define TX_PLENGTH      (*(volatile unsigned long *)(USB_BASE_ADDR + 0x24))
+#define USB_CTRL        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x28))
+
+/* USB Device DMA Registers */
+#define DMA_REQ_STAT        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x50))
+#define DMA_REQ_CLR         (*(volatile unsigned long *)(USB_BASE_ADDR + 0x54))
+#define DMA_REQ_SET         (*(volatile unsigned long *)(USB_BASE_ADDR + 0x58))
+#define UDCA_HEAD           (*(volatile unsigned long *)(USB_BASE_ADDR + 0x80))
+#define EP_DMA_STAT         (*(volatile unsigned long *)(USB_BASE_ADDR + 0x84))
+#define EP_DMA_EN           (*(volatile unsigned long *)(USB_BASE_ADDR + 0x88))
+#define EP_DMA_DIS          (*(volatile unsigned long *)(USB_BASE_ADDR + 0x8C))
+#define DMA_INT_STAT        (*(volatile unsigned long *)(USB_BASE_ADDR + 0x90))
+#define DMA_INT_EN          (*(volatile unsigned long *)(USB_BASE_ADDR + 0x94))
+#define EOT_INT_STAT        (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA0))
+#define EOT_INT_CLR         (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA4))
+#define EOT_INT_SET         (*(volatile unsigned long *)(USB_BASE_ADDR + 0xA8))
+#define NDD_REQ_INT_STAT    (*(volatile unsigned long *)(USB_BASE_ADDR + 0xAC))
+#define NDD_REQ_INT_CLR     (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB0))
+#define NDD_REQ_INT_SET     (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB4))
+#define SYS_ERR_INT_STAT    (*(volatile unsigned long *)(USB_BASE_ADDR + 0xB8))
+#define SYS_ERR_INT_CLR     (*(volatile unsigned long *)(USB_BASE_ADDR + 0xBC))
+#define SYS_ERR_INT_SET     (*(volatile unsigned long *)(USB_BASE_ADDR + 0xC0))
+
+/* USB Host and OTG registers are for LPC24xx only */
+/* USB Host Controller */
+#define USBHC_BASE_ADDR		0xFFE0C000
+#define HC_REVISION         (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x00))
+#define HC_CONTROL          (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x04))
+#define HC_CMD_STAT         (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x08))
+#define HC_INT_STAT         (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x0C))
+#define HC_INT_EN           (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x10))
+#define HC_INT_DIS          (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x14))
+#define HC_HCCA             (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x18))
+#define HC_PERIOD_CUR_ED    (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x1C))
+#define HC_CTRL_HEAD_ED     (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x20))
+#define HC_CTRL_CUR_ED      (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x24))
+#define HC_BULK_HEAD_ED     (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x28))
+#define HC_BULK_CUR_ED      (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x2C))
+#define HC_DONE_HEAD        (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x30))
+#define HC_FM_INTERVAL      (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x34))
+#define HC_FM_REMAINING     (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x38))
+#define HC_FM_NUMBER        (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x3C))
+#define HC_PERIOD_START     (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x40))
+#define HC_LS_THRHLD        (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x44))
+#define HC_RH_DESCA         (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x48))
+#define HC_RH_DESCB         (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x4C))
+#define HC_RH_STAT          (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x50))
+#define HC_RH_PORT_STAT1    (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x54))
+#define HC_RH_PORT_STAT2    (*(volatile unsigned long *)(USBHC_BASE_ADDR + 0x58))
+
+/* USB OTG Controller */
+#define USBOTG_BASE_ADDR	0xFFE0C100
+#define OTG_INT_STAT        (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x00))
+#define OTG_INT_EN          (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x04))
+#define OTG_INT_SET         (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x08))
+#define OTG_INT_CLR         (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x0C))
+/* On LPC23xx, the name is USBPortSel, on LPC24xx, the name is OTG_STAT_CTRL */ 
+#define OTG_STAT_CTRL       (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x10))
+#define OTG_TIMER           (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x14))
+
+#define USBOTG_I2C_BASE_ADDR	0xFFE0C300
+#define OTG_I2C_RX          (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x00))
+#define OTG_I2C_TX          (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x00))
+#define OTG_I2C_STS         (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x04))
+#define OTG_I2C_CTL         (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x08))
+#define OTG_I2C_CLKHI       (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x0C))
+#define OTG_I2C_CLKLO       (*(volatile unsigned long *)(USBOTG_I2C_BASE_ADDR + 0x10))
+
+/* On LPC23xx, the names are USBClkCtrl and USBClkSt; on LPC24xx, the names are 
+OTG_CLK_CTRL and OTG_CLK_STAT respectively. */
+#define USBOTG_CLK_BASE_ADDR	0xFFE0CFF0
+#define OTG_CLK_CTRL        (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x04))
+#define OTG_CLK_STAT        (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x08))
+
+/* Note: below three register name convention is for LPC23xx USB device only, match
+with the spec. update in USB Device Section. */ 
+#define USBPortSel          (*(volatile unsigned long *)(USBOTG_BASE_ADDR + 0x10))
+#define USBClkCtrl          (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x04))
+#define USBClkSt            (*(volatile unsigned long *)(USBOTG_CLK_BASE_ADDR + 0x08))
+
+/* Ethernet MAC (32 bit data bus) -- all registers are RW unless indicated in parentheses */
+#define MAC_BASE_ADDR		0xFFE00000 /* AHB Peripheral # 0 */
+#define MAC_MAC1            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x000)) /* MAC config reg 1 */
+#define MAC_MAC2            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x004)) /* MAC config reg 2 */
+#define MAC_IPGT            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x008)) /* b2b InterPacketGap reg */
+#define MAC_IPGR            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x00C)) /* non b2b InterPacketGap reg */
+#define MAC_CLRT            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x010)) /* CoLlision window/ReTry reg */
+#define MAC_MAXF            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x014)) /* MAXimum Frame reg */
+#define MAC_SUPP            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x018)) /* PHY SUPPort reg */
+#define MAC_TEST            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x01C)) /* TEST reg */
+#define MAC_MCFG            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x020)) /* MII Mgmt ConFiG reg */
+#define MAC_MCMD            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x024)) /* MII Mgmt CoMmanD reg */
+#define MAC_MADR            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x028)) /* MII Mgmt ADdRess reg */
+#define MAC_MWTD            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x02C)) /* MII Mgmt WriTe Data reg (WO) */
+#define MAC_MRDD            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x030)) /* MII Mgmt ReaD Data reg (RO) */
+#define MAC_MIND            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x034)) /* MII Mgmt INDicators reg (RO) */
+
+#define MAC_SA0             (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x040)) /* Station Address 0 reg */
+#define MAC_SA1             (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x044)) /* Station Address 1 reg */
+#define MAC_SA2             (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x048)) /* Station Address 2 reg */
+
+#define MAC_COMMAND         (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x100)) /* Command reg */
+#define MAC_STATUS          (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x104)) /* Status reg (RO) */
+#define MAC_RXDESCRIPTOR    (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x108)) /* Rx descriptor base address reg */
+#define MAC_RXSTATUS        (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x10C)) /* Rx status base address reg */
+#define MAC_RXDESCRIPTORNUM (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x110)) /* Rx number of descriptors reg */
+#define MAC_RXPRODUCEINDEX  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x114)) /* Rx produce index reg (RO) */
+#define MAC_RXCONSUMEINDEX  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x118)) /* Rx consume index reg */
+#define MAC_TXDESCRIPTOR    (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x11C)) /* Tx descriptor base address reg */
+#define MAC_TXSTATUS        (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x120)) /* Tx status base address reg */
+#define MAC_TXDESCRIPTORNUM (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x124)) /* Tx number of descriptors reg */
+#define MAC_TXPRODUCEINDEX  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x128)) /* Tx produce index reg */
+#define MAC_TXCONSUMEINDEX  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x12C)) /* Tx consume index reg (RO) */
+
+#define MAC_TSV0            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x158)) /* Tx status vector 0 reg (RO) */
+#define MAC_TSV1            (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x15C)) /* Tx status vector 1 reg (RO) */
+#define MAC_RSV             (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x160)) /* Rx status vector reg (RO) */
+
+#define MAC_FLOWCONTROLCNT  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x170)) /* Flow control counter reg */
+#define MAC_FLOWCONTROLSTS  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x174)) /* Flow control status reg */
+
+#define MAC_RXFILTERCTRL    (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x200)) /* Rx filter ctrl reg */
+#define MAC_RXFILTERWOLSTS  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x204)) /* Rx filter WoL status reg (RO) */
+#define MAC_RXFILTERWOLCLR  (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x208)) /* Rx filter WoL clear reg (WO) */
+
+#define MAC_HASHFILTERL     (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x210)) /* Hash filter LSBs reg */
+#define MAC_HASHFILTERH     (*(volatile unsigned long *)(MAC_BASE_ADDR + 0x214)) /* Hash filter MSBs reg */
+
+#define MAC_INTSTATUS       (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE0)) /* Interrupt status reg (RO) */
+#define MAC_INTENABLE       (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE4)) /* Interrupt enable reg  */
+#define MAC_INTCLEAR        (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFE8)) /* Interrupt clear reg (WO) */
+#define MAC_INTSET          (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFEC)) /* Interrupt set reg (WO) */
+
+#define MAC_POWERDOWN       (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFF4)) /* Power-down reg */
+#define MAC_MODULEID        (*(volatile unsigned long *)(MAC_BASE_ADDR + 0xFFC)) /* Module ID reg (RO) */
+
+/* LCD Controller registers */
+#define LCD_BASE_ADDR		0xFFE10000 /* AHB Peripheral # 4 */
+#define LCD_CFG             (*(volatile unsigned long *)(0xE01FC1B8))
+#define LCD_TIMH            (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x000))
+#define LCD_TIMV            (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x004))
+#define LCD_POL             (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x008))
+#define LCD_LE              (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x00C))
+#define LCD_UPBASE          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x010))
+#define LCD_LPBASE          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x014))
+#define LCD_CTRL            (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x018))
+#define LCD_INTMSK          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x01C))
+#define LCD_INTRAW          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x020))
+#define LCD_INTSTAT         (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x024))
+#define LCD_INTCLR          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x028))
+#define LCD_UPCURR          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x02C))
+#define LCD_LPCURR          (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x030))
+#define LCD_PAL             (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x200))
+#define CRSR_IMG            (*(volatile unsigned long *)(LCD_BASE_ADDR + 0x800))
+#define CRSR_CTRL           (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC00))
+#define CRSR_CFG            (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC04))
+#define CRSR_PAL0           (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC08))
+#define CRSR_PAL1           (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC0C))
+#define CRSR_XY             (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC10))
+#define CRSR_CLIP           (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC14))
+#define CRSR_INTMSK         (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC20))
+#define CRSR_INTCLR         (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC24))
+#define CRSR_INTRAW         (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC28))
+#define CRSR_INTSTAT        (*(volatile unsigned long *)(LCD_BASE_ADDR + 0xC2C))
+
+struct rt_hw_register
+{
+	unsigned long r0;
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long r10;
+	unsigned long fp;
+	unsigned long ip;
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long pc;
+	unsigned long cpsr;
+	unsigned long ORIG_r0;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // __LPC24xx_H
+

+ 99 - 0
libcpu/arm/lpc24xx/context_gcc.S

@@ -0,0 +1,99 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+
+/*!
+ * \addtogroup LPC2478
+ */
+/*@{*/
+
+#define NOINT			0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	ldr	sp, [r1]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr	sp, [r0]		@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr r2, =rt_thread_switch_interrput_flag
+	ldr r3, [r2]
+	cmp r3, #1
+	beq _reswitch
+	mov r3, #1				@ set rt_thread_switch_interrput_flag to 1
+	str r3, [r2]
+	ldr r2, =rt_interrupt_from_thread	@ set rt_interrupt_from_thread
+	str r0, [r2]
+_reswitch:
+	ldr r2, =rt_interrupt_to_thread		@ set rt_interrupt_to_thread
+	str r1, [r2]
+	mov pc, lr

+ 107 - 0
libcpu/arm/lpc24xx/context_rvds.s

@@ -0,0 +1,107 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-20     Bernard      first version
+; */
+
+NOINT	EQU		0xc0	; disable interrupt in psr
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	ARM
+	REQUIRE8
+	PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable	PROC
+	EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable	PROC
+	EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch	PROC
+	EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
+	STMFD	sp!, {r0-r12, lr}	; push lr & register file
+
+	MRS		r4, cpsr
+	STMFD	sp!, {r4}			; push cpsr
+	MRS		r4, spsr
+	STMFD	sp!, {r4}			; push spsr
+
+	STR	sp, [r0]				; store sp in preempted tasks TCB
+	LDR	sp, [r1]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to	PROC
+	EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt	PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]
+	CMP r3, #1
+	BEQ _reswitch
+	MOV r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR r3, [r2]
+	LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR r0, [r2]
+_reswitch
+	LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR r1, [r2]
+	BX	lr
+	ENDP
+
+	END

+ 42 - 0
libcpu/arm/lpc24xx/cpu.c

@@ -0,0 +1,42 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/

+ 86 - 0
libcpu/arm/lpc24xx/interrupt.c

@@ -0,0 +1,86 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+#define MAX_HANDLERS	32
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+void rt_hw_interrupt_handle(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+void rt_hw_interrupt_init()
+{
+	register int i;
+
+	rt_uint32_t *vect_addr, *vect_cntl;
+    
+	/* initialize VIC*/
+	VICIntEnClr = 0xffffffff;
+	VICVectAddr = 0;
+	VICIntSelect = 0;
+
+    for ( i = 0; i < 32; i++ )
+    {
+		vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + i*4);
+		vect_cntl = (rt_uint32_t *)(VIC_BASE_ADDR + 0x200 + i*4);
+		*vect_addr = 0x0;	
+		*vect_cntl = 0xF;
+    }
+    
+	
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+void rt_hw_interrupt_mask(int vector)
+{
+	VICIntEnClr = (1 << vector);
+}
+
+void rt_hw_interrupt_umask(int vector)
+{
+	VICIntEnable = (1 << vector);
+}
+
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	rt_uint32_t *vect_addr;
+	
+	if(vector < MAX_HANDLERS)
+	{
+		/* find first un-assigned VIC address for the handler */
+		vect_addr = (rt_uint32_t *)(VIC_BASE_ADDR + 0x100 + vector*4);
+		*vect_addr = (rt_uint32_t)new_handler;	/* set interrupt vector */
+	}
+}
+
+/*@}*/

+ 149 - 0
libcpu/arm/lpc24xx/serial.c

@@ -0,0 +1,149 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "lpc214x.h"
+#include "board.h"
+
+void rt_serial_init(void);
+
+#define PCLK		18000000
+#define BAUD_RATE	115200
+#define U0PINS  	0x00000005
+
+/**
+ * @addtogroup LPC2100
+ */
+/*@{*/
+
+/**
+ * This function is used to display a string on console, normally, it's
+ * invoked by rt_kprintf
+ *
+ * @param str the displayed string
+ */
+void rt_console_puts(const char* str)
+{
+	while (*str)
+	{
+		rt_serial_putc (*str++);
+	}
+}
+
+#define UART_RX_BUFFER_SIZE	64
+static rt_uint8_t  uart_rx_buffer[UART_RX_BUFFER_SIZE];
+static rt_uint32_t uart_read_index, uart_save_index;
+
+/**
+ * This function initializes serial
+ */
+void rt_serial_init()
+{
+	unsigned long Fdiv;
+
+	PINSEL0 = 0x00000050;       /* RxD0 and TxD0 */
+
+	rt_memset(uart_rx_buffer, 0, sizeof(uart_rx_buffer));
+	uart_read_index = uart_save_index = 0;
+
+	U0LCR = 0x83;		/* 8 bits, no Parity, 1 Stop bit */
+	/*PCLK select is 00,so /4*/
+	Fdiv = ( PCLK / 16 ) / BAUD_RATE ;	/*baud rate */
+	U0DLM = Fdiv / 256;							
+	U0DLL = Fdiv % 256;
+	U0FCR = 0x00;		/* Enable and reset TX and RX FIFO. */
+	U0LCR = 0x03;		/* DLAB = 0 */
+}
+
+/* save a char to serial buffer */
+void rt_serial_savechar(char ch)
+{
+	rt_base_t level;
+	
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	uart_rx_buffer[uart_save_index] = ch;
+	uart_save_index ++;
+	if (uart_save_index >= UART_RX_BUFFER_SIZE)
+		uart_save_index = 0;
+	
+	/* if the next position is read index, discard this 'read char' */
+	if (uart_save_index == uart_read_index)
+	{
+		uart_read_index ++;
+		if (uart_read_index >= UART_RX_BUFFER_SIZE)
+			uart_read_index = 0;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+}
+
+/**
+ * This function read a character from serial without interrupt enable mode
+ *
+ * @return the read char
+ */
+char rt_serial_getc()
+{
+	char ch;
+	rt_base_t level;
+	
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+	
+	if (uart_read_index != uart_save_index)
+	{
+		ch = uart_rx_buffer[uart_read_index];
+
+		uart_read_index ++;
+		if (uart_read_index >= UART_RX_BUFFER_SIZE)
+			uart_read_index = 0;
+		
+		/* enable interrupt */
+		rt_hw_interrupt_enable(level);
+		
+		return ch;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+
+	return 0;
+}
+
+/**
+ * This function will write a character to serial without interrupt enable mode
+ *
+ * @param c the char to write
+ */
+void rt_serial_putc(const char c)
+{
+	/*
+		to be polite with serial console add a line feed
+		to the carriage return character
+	*/
+	if (c=='\n')
+	{
+		while (!(U0LSR & 0x20));
+		U0THR = '\r';
+	}
+
+	while (!(U0LSR & 0x20));
+	U0THR = c;
+}
+
+/*@}*/

+ 60 - 0
libcpu/arm/lpc24xx/stack.c

@@ -0,0 +1,60 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+#include <rtthread.h>
+#include "LPC24xx.h"
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry 
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk) 	 = (unsigned long)tentry;		/* entry point */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 214 - 0
libcpu/arm/lpc24xx/start_gcc.S

@@ -0,0 +1,214 @@
+/*
+ * File      : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+#define WDMOD          (0xE0000000 + 0x00)
+#define VICIntEnClr    (0xFFFFF000 + 0x014)
+#define VICVectAddr    (0xFFFFF000 + 0xF00)
+#define VICIntSelect   (0xFFFFF000 + 0x00C)
+#define PLLCFG         (0xE01FC000 + 0x084)
+#define PLLCON         (0xE01FC000 + 0x080)
+#define PLLFEED        (0xE01FC000 + 0x08C)
+#define PLLSTAT        (0xE01FC000 + 0x088)
+#define CCLKCFG        (0xE01FC000 + 0x104)
+#define MEMMAP         (0xE01FC000 + 0x040)	
+#define SCS            (0xE01FC000 + 0x1A0)	
+#define CLKSRCSEL      (0xE01FC000 + 0x10C)
+#define MAMCR          (0xE01FC000 + 0x000)
+#define MAMTIM         (0xE01FC000 + 0x004)
+
+
+/*.section .init, "ax"*/
+.section .vectors
+.code 32
+.globl _start
+_start:
+	b reset
+	ldr	pc, _vector_undef
+	ldr	pc, _vector_swi
+	ldr	pc, _vector_pabt
+	ldr	pc, _vector_dabt
+	ldr	pc, _vector_resv
+	ldr	pc, _vector_irq
+	ldr	pc, _vector_fiq
+
+_vector_undef:	.word vector_undef
+_vector_swi:	.word vector_swi
+_vector_pabt:	.word vector_pabt
+_vector_dabt:	.word vector_dabt
+_vector_resv:	.word vector_resv
+_vector_irq:	.word vector_irq
+_vector_fiq:	.word vector_fiq
+
+.text
+.code 32
+
+/* the system entry */
+reset:
+	/* enter svc mode */
+	msr cpsr_c, #SVCMODE|NOINT
+	
+	/*watch dog disable */
+	ldr r0,=WDMOD
+	ldr r1,=0x0 		
+	str r1,[r0]
+	
+	/* all interrupt disable */
+	ldr r0,=VICIntEnClr
+	ldr r1,=0xffffffff
+	str r1,[r0]
+	
+	ldr	r1, =VICVectAddr
+	ldr	r0, =0x00
+	str	r0, [r1]
+	
+	ldr	r1, =VICIntSelect
+	ldr	r0, =0x00
+	str	r0, [r1]	
+	
+	/* setup stack */
+	bl stack_setup		
+
+_rtthread_startup: .word rtthread_startup
+
+	.equ USERMODE, 	0x10
+	.equ FIQMODE, 	0x11
+	.equ IRQMODE, 	0x12
+	.equ SVCMODE, 	0x13
+	.equ ABORTMODE, 0x17
+	.equ UNDEFMODE, 0x1b
+	.equ MODEMASK, 	0x1f
+	.equ NOINT,		0xc0
+
+/* exception handlers */
+vector_undef:	bl rt_hw_trap_udef
+vector_swi:		bl rt_hw_trap_swi
+vector_pabt: 	bl rt_hw_trap_pabt
+vector_dabt:	bl rt_hw_trap_dabt
+vector_resv: 	bl rt_hw_trap_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:	
+	stmfd	sp!, {r0-r12,lr}
+	bl	rt_interrupt_enter
+	bl	rt_hw_trap_irq
+	bl	rt_interrupt_leave
+
+	/* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
+	ldr	r0, =rt_thread_switch_interrput_flag
+	ldr	r1, [r0]
+	cmp	r1, #1
+	beq	_interrupt_thread_switch
+
+	ldmfd	sp!, {r0-r12,lr}
+	subs	pc, lr, #4
+
+	.align	5
+vector_fiq:
+	stmfd sp!,{r0-r7,lr}
+	bl rt_hw_trap_fiq
+	ldmfd sp!,{r0-r7,lr}
+	subs pc,lr,#4
+
+_interrupt_thread_switch:
+	mov	r1, #0				@ clear rt_thread_switch_interrput_flag
+	str	r1, [r0]
+
+	ldmfd sp!, {r0-r12,lr}	@ reload saved registers
+	stmfd sp!, {r0-r3}		@ save r0-r3
+	mov	r1, sp
+	add	sp, sp, #16			@ restore sp
+	sub	r2, lr, #4			@ save old task's pc to r2
+
+	mrs	r3, spsr			@ disable interrupt
+	orr	r0, r3, #NOINT
+	msr	spsr_c, r0
+
+	ldr	r0,  =.+8			@ switch to interrupted task's stack
+	movs pc, r0
+
+	stmfd sp!, {r2}			@ push old task's pc
+	stmfd sp!, {r4-r12,lr}	@ push old task's lr,r12-r4
+	mov	r4, r1				@ Special optimised code below
+	mov	r5, r3
+	ldmfd r4!, {r0-r3}
+	stmfd sp!, {r0-r3}		@ push old task's r3-r0
+	stmfd sp!, {r5}			@ push old task's psr
+	mrs	r4, spsr
+	stmfd sp!, {r4}			@ push old task's spsr
+
+	ldr	r4, =rt_interrupt_from_thread
+	ldr	r5, [r4]
+	str	sp, [r5]			@ store sp in preempted tasks's TCB
+
+	ldr	r6, =rt_interrupt_to_thread
+	ldr	r6, [r6]
+	ldr	sp, [r6]			@ get new task's stack pointer
+
+	ldmfd sp!, {r4}			@ pop new task's spsr
+	msr	SPSR_cxsf, r4
+	ldmfd sp!, {r4}			@ pop new task's psr
+	msr CPSR_cxsf, r4
+
+	ldmfd sp!, {r0-r12,lr,pc}	@ pop new task's r0-r12,lr & pc
+
+/* each mode stack memory */
+stack_setup:
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK
+	orr	r1, r0, #UNDEFMODE|NOINT
+	msr	cpsr_cxsf, r1		@ undef mode
+	ldr	sp, =__UndStack_end
+
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK
+	orr	r1,r0,#ABORTMODE|NOINT
+	msr	cpsr_cxsf,r1		@ abort mode
+	ldr	sp,=__ABTStack_end
+
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK
+	orr	r1,r0,#IRQMODE|NOINT
+	msr	cpsr_cxsf,r1		@ IRQ mode
+	ldr	sp,=__IRQStack_end
+
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK
+	orr	r1,r0,#FIQMODE|NOINT
+	msr	cpsr_cxsf,r1		@ FIQ mode
+	ldr	sp,=__FIQStack_end
+
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK
+	orr	r1,r0,#SVCMODE|NOINT
+	msr	cpsr_cxsf,r1		@ SVC mode
+	ldr	sp,=__SVCStack_end
+
+	/* USER mode is not initialized. */
+	mrs	r0, cpsr
+	bic	r0, r0, #MODEMASK|0x80		//IRQ enable and FIQ disable
+	orr	r1,r0,#USERMODE
+	msr	cpsr_cxsf,r1		@ usr mode	
+	ldr	sp,=__USRStack_end		
+		
+	ldr	pc, _rtthread_startup
+

+ 1581 - 0
libcpu/arm/lpc24xx/start_rvds.s

@@ -0,0 +1,1581 @@
+;/*****************************************************************************/
+;/* LPC2400.S: Startup file for Philips LPC2400 device series                 */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>>                          */
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools.                   */
+;/* Copyright (c) 2007-2008 Keil - An ARM Company. All rights reserved.       */
+;/* This software may only be used under the terms of a valid, current,       */
+;/* end user licence from KEIL for a compatible version of KEIL software      */
+;/* development tools. Nothing else gives you the right to use this software. */
+;/*****************************************************************************/
+
+;/*
+; *  The LPC2400.S code is executed after CPU Reset. This file may be 
+; *  translated with the following SET symbols. In uVision these SET 
+; *  symbols are entered under Options - ASM - Define.
+; *
+; *  NO_CLOCK_SETUP: when set the startup code will not initialize Clock 
+; *  (used mostly when clock is already initialized from script .ini 
+; *  file).
+; *
+; *  NO_EMC_SETUP: when set the startup code will not initialize 
+; *  External Bus Controller.
+; *
+; *  RAM_INTVEC: when set the startup code copies exception vectors 
+; *  from on-chip Flash to on-chip RAM.
+; *
+; *  REMAP: when set the startup code initializes the register MEMMAP 
+; *  which overwrites the settings of the CPU configuration pins. The 
+; *  startup and interrupt vectors are remapped from:
+; *     0x00000000  default setting (not remapped)
+; *     0x40000000  when RAM_MODE is used
+; *     0x80000000  when EXTMEM_MODE is used
+; *
+; *  EXTMEM_MODE: when set the device is configured for code execution
+; *  from external memory starting at address 0x80000000.
+; *
+; *  RAM_MODE: when set the device is configured for code execution
+; *  from on-chip RAM starting at address 0x40000000. 
+; */
+
+
+; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+
+Mode_USR        EQU     0x10
+Mode_FIQ        EQU     0x11
+Mode_IRQ        EQU     0x12
+Mode_SVC        EQU     0x13
+Mode_ABT        EQU     0x17
+Mode_UND        EQU     0x1B
+Mode_SYS        EQU     0x1F
+
+I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
+F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
+
+
+;----------------------- Memory Definitions ------------------------------------
+
+; Internal Memory Base Addresses
+FLASH_BASE      EQU     0x00000000   
+RAM_BASE        EQU     0x40000000
+EXTMEM_BASE     EQU     0x80000000
+
+; External Memory Base Addresses
+STA_MEM0_BASE   EQU     0x80000000
+STA_MEM1_BASE   EQU     0x81000000
+STA_MEM2_BASE   EQU     0x82000000
+STA_MEM3_BASE   EQU     0x83000000
+DYN_MEM0_BASE   EQU     0xA0000000   
+DYN_MEM1_BASE   EQU     0xB0000000   
+DYN_MEM2_BASE   EQU     0xC0000000   
+DYN_MEM3_BASE   EQU     0xD0000000   
+
+
+;----------------------- Stack and Heap Definitions ----------------------------
+
+;// <h> Stack Configuration (Stack Sizes in Bytes)
+;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
+;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
+;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
+;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
+;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
+;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
+;// </h>
+
+UND_Stack_Size  EQU     0x00000000
+SVC_Stack_Size  EQU     0x00000100
+ABT_Stack_Size  EQU     0x00000000
+FIQ_Stack_Size  EQU     0x00000000
+IRQ_Stack_Size  EQU     0x00000100
+USR_Stack_Size  EQU     0x00000100
+
+ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                         FIQ_Stack_Size + IRQ_Stack_Size)
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem       SPACE   USR_Stack_Size
+__initial_sp    SPACE   ISR_Stack_Size
+
+Stack_Top
+
+
+;// <h> Heap Configuration
+;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
+;// </h>
+
+Heap_Size       EQU     0x00000000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+;----------------------- Clock Definitions -------------------------------------
+
+; System Control Block (SCB) Module Definitions
+SCB_BASE        EQU     0xE01FC000      ; SCB Base Address
+PLLCON_OFS      EQU     0x80            ; PLL Control Offset
+PLLCFG_OFS      EQU     0x84            ; PLL Configuration Offset
+PLLSTAT_OFS     EQU     0x88            ; PLL Status Offset
+PLLFEED_OFS     EQU     0x8C            ; PLL Feed Offset
+CCLKCFG_OFS     EQU     0x104           ; CPU Clock Divider Reg Offset
+USBCLKCFG_OFS   EQU     0x108           ; USB Clock Divider Reg Offset
+CLKSRCSEL_OFS   EQU     0x10C           ; Clock Source Sel Reg Offset
+SCS_OFS         EQU     0x1A0           ; Sys Control and Status Reg Offset
+PCLKSEL0_OFS    EQU     0x1A8           ; Periph Clock Sel Reg 0 Offset
+PCLKSEL1_OFS    EQU     0x1AC           ; Periph Clock Sel Reg 0 Offset
+
+PCON_OFS        EQU     0x0C0           ; Power Mode Control Reg Offset
+PCONP_OFS       EQU     0x0C4           ; Power Control for Periphs Reg Offset
+
+; Constants
+OSCRANGE        EQU     (1<<4)          ; Oscillator Range Select
+OSCEN           EQU     (1<<5)          ; Main oscillator Enable
+OSCSTAT         EQU     (1<<6)          ; Main Oscillator Status
+PLLCON_PLLE     EQU     (1<<0)          ; PLL Enable
+PLLCON_PLLC     EQU     (1<<1)          ; PLL Connect
+PLLSTAT_M       EQU     (0x7FFF<<0)     ; PLL M Value
+PLLSTAT_N       EQU     (0xFF<<16)      ; PLL N Value
+PLLSTAT_PLOCK   EQU     (1<<26)         ; PLL Lock Status
+
+;// <e> Clock Setup
+;//   <h> System Controls and Status Register (SYS)
+;//     <o1.4>    OSCRANGE: Main Oscillator Range Select
+;//                     <0=>  1 MHz to 20 MHz
+;//                     <1=> 15 MHz to 24 MHz
+;//     <e1.5>       OSCEN: Main Oscillator Enable
+;//     </e>
+;//   </h>
+;//
+;//   <h> PLL Clock Source Select Register (CLKSRCSEL)
+;//     <o2.0..1>   CLKSRC: PLL Clock Source Selection
+;//                     <0=> Internal RC oscillator
+;//                     <1=> Main oscillator
+;//                     <2=> RTC oscillator
+;//   </h>
+;//
+;//   <h> PLL Configuration Register (PLLCFG)
+;//                     <i> PLL_clk = (2* M * PLL_clk_src) / N
+;//     <o3.0..14>    MSEL: PLL Multiplier Selection
+;//                     <1-32768><#-1>
+;//                     <i> M Value
+;//     <o3.16..23>   NSEL: PLL Divider Selection
+;//                     <1-256><#-1>
+;//                     <i> N Value
+;//   </h>
+;//
+;//   <h> CPU Clock Configuration Register (CCLKCFG)
+;//     <o4.0..7>  CCLKSEL: Divide Value for CPU Clock from PLL
+;//                     <1-256><#-1>
+;//   </h>
+;//
+;//   <h> USB Clock Configuration Register (USBCLKCFG)
+;//     <o5.0..3>   USBSEL: Divide Value for USB Clock from PLL
+;//                     <1-16><#-1>
+;//   </h>
+;//
+;//   <h> Peripheral Clock Selection Register 0 (PCLKSEL0)
+;//     <o6.0..1>      PCLK_WDT: Peripheral Clock Selection for WDT
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.2..3>   PCLK_TIMER0: Peripheral Clock Selection for TIMER0
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.4..5>   PCLK_TIMER1: Peripheral Clock Selection for TIMER1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.6..7>    PCLK_UART0: Peripheral Clock Selection for UART0
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.8..9>    PCLK_UART1: Peripheral Clock Selection for UART1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.10..11>   PCLK_PWM0: Peripheral Clock Selection for PWM0
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.12..13>   PCLK_PWM1: Peripheral Clock Selection for PWM1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.14..15>   PCLK_I2C0: Peripheral Clock Selection for I2C0
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.16..17>    PCLK_SPI: Peripheral Clock Selection for SPI
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.18..19>    PCLK_RTC: Peripheral Clock Selection for RTC
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.20..21>   PCLK_SSP1: Peripheral Clock Selection for SSP1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.22..23>    PCLK_DAC: Peripheral Clock Selection for DAC
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.24..25>    PCLK_ADC: Peripheral Clock Selection for ADC
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o6.26..27>   PCLK_CAN1: Peripheral Clock Selection for CAN1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 6
+;//     <o6.28..29>   PCLK_CAN2: Peripheral Clock Selection for CAN2
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 6
+;//     <o6.30..31>    PCLK_ACF: Peripheral Clock Selection for ACF
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 6
+;//   </h>
+;//
+;//   <h> Peripheral Clock Selection Register 1 (PCLKSEL1)
+;//     <o7.0..1>  PCLK_BAT_RAM: Peripheral Clock Selection for the Battery Supported RAM
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.2..3>     PCLK_GPIO: Peripheral Clock Selection for GPIOs
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.4..5>      PCLK_PCB: Peripheral Clock Selection for Pin Connect Block
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.6..7>     PCLK_I2C1: Peripheral Clock Selection for I2C1
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.10..11>   PCLK_SSP0: Peripheral Clock Selection for SSP0
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.16..17>  PCLK_UART2: Peripheral Clock Selection for UART2
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.18..19>  PCLK_UART3: Peripheral Clock Selection for UART3
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.20..21>   PCLK_I2C2: Peripheral Clock Selection for I2C2
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.22..23>    PCLK_I2S: Peripheral Clock Selection for I2S
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.24..25>    PCLK_MCI: Peripheral Clock Selection for MCI
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//     <o7.28..29> PCLK_SYSCON: Peripheral Clock Selection for System Control Block
+;//                     <0=> Pclk = Cclk / 4
+;//                     <1=> Pclk = Cclk
+;//                     <2=> Pclk = Cclk / 2
+;//                     <3=> Pclk = Cclk / 8
+;//   </h>
+;// </e>
+CLOCK_SETUP     EQU     1
+SCS_Val         EQU     0x00000020
+CLKSRCSEL_Val   EQU     0x00000001
+PLLCFG_Val      EQU     0x0000000B
+CCLKCFG_Val     EQU     0x00000004
+USBCLKCFG_Val   EQU     0x00000005
+PCLKSEL0_Val    EQU     0x00000000
+PCLKSEL1_Val    EQU     0x00000000
+
+
+;----------------------- Memory Accelerator Module (MAM) Definitions -----------
+
+MAM_BASE        EQU     0xE01FC000      ; MAM Base Address
+MAMCR_OFS       EQU     0x00            ; MAM Control Offset
+MAMTIM_OFS      EQU     0x04            ; MAM Timing Offset
+
+;// <e> MAM Setup
+;//   <o1.0..1>   MAM Control
+;//               <0=> Disabled
+;//               <1=> Partially Enabled
+;//               <2=> Fully Enabled
+;//               <i> Mode
+;//   <o2.0..2>   MAM Timing
+;//               <0=> Reserved  <1=> 1   <2=> 2   <3=> 3
+;//               <4=> 4         <5=> 5   <6=> 6   <7=> 7
+;//               <i> Fetch Cycles
+;// </e>
+MAM_SETUP       EQU     1
+MAMCR_Val       EQU     0x00000002
+MAMTIM_Val      EQU     0x00000004
+
+
+;----------------------- Pin Connect Block Definitions -------------------------
+
+PCB_BASE            EQU 0xE002C000      ; PCB Base Address
+PINSEL0_OFS         EQU 0x00            ; PINSEL0  Address Offset
+PINSEL1_OFS         EQU 0x04            ; PINSEL1  Address Offset
+PINSEL2_OFS         EQU 0x08            ; PINSEL2  Address Offset
+PINSEL3_OFS         EQU 0x0C            ; PINSEL3  Address Offset
+PINSEL4_OFS         EQU 0x10            ; PINSEL4  Address Offset
+PINSEL5_OFS         EQU 0x14            ; PINSEL5  Address Offset
+PINSEL6_OFS         EQU 0x18            ; PINSEL6  Address Offset
+PINSEL7_OFS         EQU 0x1C            ; PINSEL7  Address Offset
+PINSEL8_OFS         EQU 0x20            ; PINSEL8  Address Offset
+PINSEL9_OFS         EQU 0x24            ; PINSEL9  Address Offset
+PINSEL10_OFS        EQU 0x28            ; PINSEL10 Address Offset
+
+
+;----------------------- External Memory Controller (EMC) Definitons -----------
+
+EMC_BASE            EQU 0xFFE08000      ; EMC Base Address
+
+EMC_CTRL_OFS        EQU 0x000
+EMC_STAT_OFS        EQU 0x004
+EMC_CONFIG_OFS      EQU 0x008
+EMC_DYN_CTRL_OFS    EQU 0x020
+EMC_DYN_RFSH_OFS    EQU 0x024
+EMC_DYN_RD_CFG_OFS  EQU 0x028
+EMC_DYN_RP_OFS      EQU 0x030
+EMC_DYN_RAS_OFS     EQU 0x034
+EMC_DYN_SREX_OFS    EQU 0x038
+EMC_DYN_APR_OFS     EQU 0x03C
+EMC_DYN_DAL_OFS     EQU 0x040
+EMC_DYN_WR_OFS      EQU 0x044
+EMC_DYN_RC_OFS      EQU 0x048
+EMC_DYN_RFC_OFS     EQU 0x04C
+EMC_DYN_XSR_OFS     EQU 0x050
+EMC_DYN_RRD_OFS     EQU 0x054
+EMC_DYN_MRD_OFS     EQU 0x058
+EMC_DYN_CFG0_OFS    EQU 0x100
+EMC_DYN_RASCAS0_OFS EQU 0x104
+EMC_DYN_CFG1_OFS    EQU 0x140
+EMC_DYN_RASCAS1_OFS EQU 0x144
+EMC_DYN_CFG2_OFS    EQU 0x160
+EMC_DYN_RASCAS2_OFS EQU 0x164
+EMC_DYN_CFG3_OFS    EQU 0x180
+EMC_DYN_RASCAS3_OFS EQU 0x184
+EMC_STA_CFG0_OFS    EQU 0x200
+EMC_STA_WWEN0_OFS   EQU 0x204
+EMC_STA_WOEN0_OFS   EQU 0x208
+EMC_STA_WRD0_OFS    EQU 0x20C
+EMC_STA_WPAGE0_OFS  EQU 0x210
+EMC_STA_WWR0_OFS    EQU 0x214
+EMC_STA_WTURN0_OFS  EQU 0x218
+EMC_STA_CFG1_OFS    EQU 0x220
+EMC_STA_WWEN1_OFS   EQU 0x224
+EMC_STA_WOEN1_OFS   EQU 0x228
+EMC_STA_WRD1_OFS    EQU 0x22C
+EMC_STA_WPAGE1_OFS  EQU 0x230
+EMC_STA_WWR1_OFS    EQU 0x234
+EMC_STA_WTURN1_OFS  EQU 0x238
+EMC_STA_CFG2_OFS    EQU 0x240
+EMC_STA_WWEN2_OFS   EQU 0x244
+EMC_STA_WOEN2_OFS   EQU 0x248
+EMC_STA_WRD2_OFS    EQU 0x24C
+EMC_STA_WPAGE2_OFS  EQU 0x250
+EMC_STA_WWR2_OFS    EQU 0x254
+EMC_STA_WTURN2_OFS  EQU 0x258
+EMC_STA_CFG3_OFS    EQU 0x260
+EMC_STA_WWEN3_OFS   EQU 0x264
+EMC_STA_WOEN3_OFS   EQU 0x268
+EMC_STA_WRD3_OFS    EQU 0x26C
+EMC_STA_WPAGE3_OFS  EQU 0x270
+EMC_STA_WWR3_OFS    EQU 0x274
+EMC_STA_WTURN3_OFS  EQU 0x278
+EMC_STA_EXT_W_OFS   EQU 0x880
+
+; Constants
+NORMAL_CMD          EQU (0x0 << 7)      ; NORMAL        Command
+MODE_CMD            EQU (0x1 << 7)      ; MODE          Command
+PALL_CMD            EQU (0x2 << 7)      ; Precharge All Command
+NOP_CMD             EQU (0x3 << 7)      ; NOP           Command
+
+BUFEN_Const         EQU (1 << 19)       ; Buffer enable bit
+EMC_PCONP_Const     EQU (1 << 11)       ; PCONP val to enable power for EMC
+
+; External Memory Pins definitions
+; pin functions for SDRAM, NOR and NAND flash interfacing
+EMC_PINSEL5_Val     EQU 0x05010115      ; !CAS, !RAS, CLKOUT0, !DYCS0, DQMOUT0, DQMOUT1
+EMC_PINSEL6_Val     EQU 0x55555555      ; D0 .. D15
+EMC_PINSEL8_Val     EQU 0x55555555      ; A0 .. A15
+EMC_PINSEL9_Val     EQU 0x50055555;     ; A16 .. A23, !OE, !WE, !CS0, !CS1
+
+;//     External Memory Controller Setup (EMC) ---------------------------------
+;// <e> External Memory Controller Setup (EMC)
+EMC_SETUP           EQU 0
+
+;//   <h> EMC Control Register (EMCControl)
+;//     <i> Controls operation of the memory controller
+;//     <o0.2> L: Low-power mode enable
+;//     <o0.1> M: Address mirror enable
+;//     <o0.0> E: EMC enable
+;//   </h>
+EMC_CTRL_Val        EQU 0x00000001
+
+;//   <h> EMC Configuration Register (EMCConfig)
+;//     <i> Configures operation of the memory controller
+;//     <o0.8> CCLK: CLKOUT ratio
+;//       <0=> 1:1
+;//       <1=> 1:2
+;//     <o0.0> Endian mode
+;//       <0=> Little-endian
+;//       <1=> Big-endian
+;//   </h>
+EMC_CONFIG_Val      EQU 0x00000000
+
+;//       Dynamic Memory Interface Setup ---------------------------------------
+;//   <e> Dynamic Memory Interface Setup
+EMC_DYNAMIC_SETUP   EQU 1
+
+;//     <h> Dynamic Memory Refresh Timer Register (EMCDynamicRefresh)
+;//       <i> Configures dynamic memory refresh operation
+;//       <o0.0..10> REFRESH: Refresh timer <0x000-0x7FF>
+;//         <i> 0 = refresh disabled, 0x01-0x7FF: value * 16 CCLKS
+;//     </h>
+EMC_DYN_RFSH_Val    EQU 0x0000001C
+
+;//     <h> Dynamic Memory Read Configuration Register (EMCDynamicReadConfig)
+;//       <i> Configures the dynamic memory read strategy
+;//       <o0.0..1> RD: Read data strategy
+;//                  <0=> Clock out delayed strategy
+;//         <1=> Command delayed strategy
+;//         <2=> Command delayed strategy plus one clock cycle
+;//         <3=> Command delayed strategy plus two clock cycles
+;//     </h>
+EMC_DYN_RD_CFG_Val  EQU 0x00000001
+
+;//     <h> Dynamic Memory Timings
+;//       <h> Dynamic Memory Percentage Command Period Register (EMCDynamictRP)
+;//         <o0.0..3> tRP: Precharge command period <1-16> <#-1>
+;//           <i> The delay is in EMCCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tRP
+;//       </h>
+;//       <h> Dynamic Memory Active to Precharge Command Period Register (EMCDynamictRAS)
+;//         <o1.0..3> tRAS: Active to precharge command period <1-16> <#-1>
+;//           <i> The delay is in EMCCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tRAS
+;//       </h>
+;//       <h> Dynamic Memory Self-refresh Exit Time Register (EMCDynamictSREX)
+;//         <o2.0..3> tSREX: Self-refresh exit time <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tSREX, 
+;//           <i> for devices without this parameter you use the same value as tXSR
+;//       </h>
+;//       <h> Dynamic Memory Last Data Out to Active Time Register (EMCDynamictAPR)
+;//         <o3.0..3> tAPR: Last-data-out to active command time <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tAPR
+;//       </h>
+;//       <h> Dynamic Memory Data-in to Active Command Time Register (EMCDynamictDAL)
+;//         <o4.0..3> tDAL: Data-in to active command time <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tDAL or tAPW
+;//       </h>
+;//       <h> Dynamic Memory Write Recovery Time Register (EMCDynamictWR)
+;//         <o5.0..3> tWR: Write recovery time <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tWR, tDPL, tRWL, or tRDL
+;//       </h>
+;//       <h> Dynamic Memory Active to Active Command Period Register (EMCDynamictRC)
+;//         <o6.0..4> tRC: Active to active command period <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tRC
+;//       </h>
+;//       <h> Dynamic Memory Auto-refresh Period Register (EMCDynamictRFC)
+;//         <o7.0..4> tRFC: Auto-refresh period and auto-refresh to active command period <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tRFC or  tRC
+;//       </h>
+;//       <h> Dynamic Memory Exit Self-refresh Register (EMCDynamictXSR)
+;//         <o8.0..4> tXSR: Exit self-refresh to active command time <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tXSR
+;//       </h>
+;//       <h> Dynamic Memory Active Bank A to Active Bank B Time Register (EMCDynamicRRD)
+;//         <o9.0..3> tRRD: Active bank A to active bank B latency <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tRRD
+;//       </h>
+;//       <h> Dynamic Memory Load Mode Register to Active Command Time (EMCDynamictMRD)
+;//         <o10.0..3> tMRD: Load mode register to active command time <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//           <i> This value is normally found in SDRAM data sheets as tMRD or tRSA
+;//       </h>
+;//     </h>
+EMC_DYN_RP_Val      EQU 0x00000002
+EMC_DYN_RAS_Val     EQU 0x00000003
+EMC_DYN_SREX_Val    EQU 0x00000007
+EMC_DYN_APR_Val     EQU 0x00000002
+EMC_DYN_DAL_Val     EQU 0x00000005
+EMC_DYN_WR_Val      EQU 0x00000001
+EMC_DYN_RC_Val      EQU 0x00000005
+EMC_DYN_RFC_Val     EQU 0x00000005
+EMC_DYN_XSR_Val     EQU 0x00000007
+EMC_DYN_RRD_Val     EQU 0x00000001
+EMC_DYN_MRD_Val     EQU 0x00000002
+
+;//     <e> Configure External Bus Behaviour for Dynamic CS0 Area
+EMC_DYNCS0_SETUP    EQU 1
+
+;//       <h> Dynamic Memory Configuration Register (EMCDynamicConfig0)
+;//         <i> Defines the configuration information for the dynamic memory CS0
+;//         <o0.20> P: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.14> AM 14: External bus data width
+;//           <0=> 16 bit
+;//           <1=> 32 bit
+;//         <o0.12> AM 12: External bus memory type
+;//           <0=> High-performance
+;//           <1=> Low-power SDRAM
+;//         <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;//           <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;//           <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;//           <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;//           <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;//           <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;//           <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;//           <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;//           <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;//           <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;//           <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;//         <o0.3..4> MD: Memory device
+;//           <0=> SDRAM
+;//           <1=> Low-power SDRAM
+;//           <2=> Micron SyncFlash
+;//       </h>
+EMC_DYN_CFG0_Val    EQU 0x00080680
+
+;//       <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS0)
+;//         <i> Controls the RAS and CAS latencies for the dynamic memory CS0
+;//         <o0.8..9> CAS: CAS latency
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//         <o0.0..1> RAS: RAS latency (active to read/write delay)
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//       </h>
+EMC_DYN_RASCAS0_Val EQU 0x00000303
+
+;//     </e> End of Dynamic Setup for CS0 Area
+
+
+;//     <e> Configure External Bus Behaviour for Dynamic CS1 Area
+EMC_DYNCS1_SETUP    EQU 0
+
+;//       <h> Dynamic Memory Configuration Register (EMCDynamicConfig1)
+;//         <i> Defines the configuration information for the dynamic memory CS1
+;//         <o0.20> P: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.14> AM 14: External bus data width
+;//           <0=> 16 bit
+;//           <1=> 32 bit
+;//         <o0.12> AM 12: External bus memory type
+;//           <0=> High-performance
+;//           <1=> Low-power SDRAM
+;//         <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;//           <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;//           <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;//           <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;//           <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;//           <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;//           <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;//           <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;//           <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;//           <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;//           <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;//         <o0.3..4> MD: Memory device
+;//           <0=> SDRAM
+;//           <1=> Low-power SDRAM
+;//           <2=> Micron SyncFlash
+;//       </h>
+EMC_DYN_CFG1_Val    EQU 0x00000000
+
+;//       <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS1)
+;//         <i> Controls the RAS and CAS latencies for the dynamic memory CS1
+;//         <o0.8..9> CAS: CAS latency
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//         <o0.0..1> RAS: RAS latency (active to read/write delay)
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//       </h>
+EMC_DYN_RASCAS1_Val EQU 0x00000303
+
+;//     </e> End of Dynamic Setup for CS1 Area
+
+;//     <e> Configure External Bus Behaviour for Dynamic CS2 Area
+EMC_DYNCS2_SETUP    EQU 0
+
+;//       <h> Dynamic Memory Configuration Register (EMCDynamicConfig2)
+;//         <i> Defines the configuration information for the dynamic memory CS2
+;//         <o0.20> P: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.14> AM 14: External bus data width
+;//           <0=> 16 bit
+;//           <1=> 32 bit
+;//         <o0.12> AM 12: External bus memory type
+;//           <0=> High-performance
+;//           <1=> Low-power SDRAM
+;//         <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;//           <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;//           <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;//           <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;//           <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;//           <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;//           <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;//           <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;//           <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;//           <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;//           <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;//         <o0.3..4> MD: Memory device
+;//           <0=> SDRAM
+;//           <1=> Low-power SDRAM
+;//           <2=> Micron SyncFlash
+;//       </h>
+EMC_DYN_CFG2_Val    EQU 0x00000000
+
+;//       <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS2)
+;//         <i> Controls the RAS and CAS latencies for the dynamic memory CS2
+;//         <o0.8..9> CAS: CAS latency
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//         <o0.0..1> RAS: RAS latency (active to read/write delay)
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//       </h>
+EMC_DYN_RASCAS2_Val EQU 0x00000303
+
+;//     </e> End of Dynamic Setup for CS2 Area
+
+;//     <e> Configure External Bus Behaviour for Dynamic CS3 Area
+EMC_DYNCS3_SETUP    EQU 0
+
+;//       <h> Dynamic Memory Configuration Register (EMCDynamicConfig3)
+;//         <i> Defines the configuration information for the dynamic memory CS3
+;//         <o0.20> P: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.14> AM 14: External bus data width
+;//           <0=> 16 bit
+;//           <1=> 32 bit
+;//         <o0.12> AM 12: External bus memory type
+;//           <0=> High-performance
+;//           <1=> Low-power SDRAM
+;//         <o0.7..11> AM 11..7: External bus address mapping (Row, Bank, Column)
+;//           <0x00=> 16 Mb = 2MB (2Mx8), 2 banks, row length = 11, column length = 9
+;//           <0x01=> 16 Mb = 2MB (1Mx16), 2 banks, row length = 11, column length = 8
+;//           <0x04=> 64 Mb = 8MB (8Mx8), 4 banks, row length = 12, column length = 9
+;//           <0x05=> 64 Mb = 8MB (4Mx16), 4 banks, row length = 12, column length = 8
+;//           <0x08=> 128 Mb = 16MB (16Mx8), 4 banks, row length = 12, column length = 10
+;//           <0x09=> 128 Mb = 16MB (8Mx16), 4 banks, row length = 12, column length = 9
+;//           <0x0C=> 256 Mb = 32MB (32Mx8), 4 banks, row length = 13, column length = 10
+;//           <0x0D=> 256 Mb = 32MB (16Mx16), 4 banks, row length = 13, column length = 9
+;//           <0x10=> 512 Mb = 64MB (64Mx8), 4 banks, row length = 13, column length = 11
+;//           <0x11=> 512 Mb = 64MB (32Mx16), 4 banks, row length = 13, column length = 10
+;//         <o0.3..4> MD: Memory device
+;//           <0=> SDRAM
+;//           <1=> Low-power SDRAM
+;//           <2=> Micron SyncFlash
+;//       </h>
+EMC_DYN_CFG3_Val    EQU 0x00000000
+
+;//       <h> Dynamic Memory RAS & CAS Delay register (EMCDynamicRASCAS3)
+;//         <i> Controls the RAS and CAS latencies for the dynamic memory CS3
+;//         <o0.8..9> CAS: CAS latency
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//         <o0.0..1> RAS: RAS latency (active to read/write delay)
+;//           <1=> One CCLK cycle
+;//           <2=> Two CCLK cycles
+;//           <3=> Three CCLK cycles
+;//       </h>
+EMC_DYN_RASCAS3_Val EQU 0x00000303
+
+;//     </e> End of Dynamic Setup for CS3 Area
+
+;//   </e> End of Dynamic Setup
+
+;//       Static Memory Interface Setup ----------------------------------------
+;//   <e> Static Memory Interface Setup
+EMC_STATIC_SETUP    EQU 1
+
+;//         Configure External Bus Behaviour for Static CS0 Area ---------------
+;//     <e> Configure External Bus Behaviour for Static CS0 Area
+EMC_STACS0_SETUP    EQU 1
+
+;//       <h> Static Memory Configuration Register (EMCStaticConfig0)
+;//         <i> Defines the configuration information for the static memory CS0
+;//         <o0.20> WP: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.8> EW: Extended wait enable
+;//         <o0.7> PB: Byte lane state
+;//           <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;//           <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;//         <o0.6> PC: Chip select polarity
+;//           <0=> Active LOW chip select
+;//           <1=> Active HIGH chip select
+;//         <o0.3> PM: Page mode enable
+;//         <o0.0..1> MW: Memory width
+;//           <0=> 8 bit
+;//           <1=> 16 bit
+;//           <2=> 32 bit
+;//       </h>
+EMC_STA_CFG0_Val    EQU 0x00000081
+
+;//       <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen0)
+;//         <i> Selects the delay from CS0 to write enable
+;//         <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWEN0_Val   EQU 0x00000002
+
+;//       <h> Static Memory Output Enable Delay register (EMCStaticWaitOen0)
+;//         <i> Selects the delay from CS0 or address change, whichever is later, to output enable
+;//         <o.0..3> WAITOEN: Wait output enable <0-15>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WOEN0_Val   EQU 0x00000002
+                                      
+;//       <h> Static Memory Read Delay Register (EMCStaticWaitRd0)
+;//         <i> Selects the delay from CS0 to a read access
+;//         <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WRD0_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0)
+;//         <i> Selects the delay for asynchronous page mode sequential accesses for CS0
+;//         <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WPAGE0_Val  EQU 0x0000001F
+
+;//       <h> Static Memory Write Delay Register (EMCStaticWaitWr0)
+;//         <i> Selects the delay from CS0 to a write access
+;//         <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWR0_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn0)
+;//         <i> Selects the number of bus turnaround cycles for CS0
+;//         <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WTURN0_Val  EQU 0x0000000F
+
+;//     </e> End of Static Setup for Static CS0 Area
+
+;//         Configure External Bus Behaviour for Static CS1 Area ---------------
+;//     <e> Configure External Bus Behaviour for Static CS1 Area
+EMC_STACS1_SETUP    EQU 0
+
+;//       <h> Static Memory Configuration Register (EMCStaticConfig1)
+;//         <i> Defines the configuration information for the static memory CS1
+;//         <o0.20> WP: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.8> EW: Extended wait enable
+;//         <o0.7> PB: Byte lane state
+;//           <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;//           <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;//         <o0.6> PC: Chip select polarity
+;//           <0=> Active LOW chip select
+;//           <1=> Active HIGH chip select
+;//         <o0.3> PM: Page mode enable
+;//         <o0.0..1> MW: Memory width
+;//           <0=> 8 bit
+;//           <1=> 16 bit
+;//           <2=> 32 bit
+;//       </h>
+EMC_STA_CFG1_Val    EQU 0x00000000
+
+;//       <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen1)
+;//         <i> Selects the delay from CS1 to write enable
+;//         <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWEN1_Val   EQU 0x00000000
+
+;//       <h> Static Memory Output Enable Delay register (EMCStaticWaitOen1)
+;//         <i> Selects the delay from CS1 or address change, whichever is later, to output enable
+;//         <o.0..3> WAITOEN: Wait output enable <0-15>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WOEN1_Val   EQU 0x00000000
+                                      
+;//       <h> Static Memory Read Delay Register (EMCStaticWaitRd1)
+;//         <i> Selects the delay from CS1 to a read access
+;//         <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WRD1_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage0)
+;//         <i> Selects the delay for asynchronous page mode sequential accesses for CS1
+;//         <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WPAGE1_Val  EQU 0x0000001F
+
+;//       <h> Static Memory Write Delay Register (EMCStaticWaitWr1)
+;//         <i> Selects the delay from CS1 to a write access
+;//         <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWR1_Val    EQU  0x0000001F
+
+;//       <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn1)
+;//         <i> Selects the number of bus turnaround cycles for CS1
+;//         <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WTURN1_Val  EQU 0x0000000F
+
+;//     </e> End of Static Setup for Static CS1 Area
+
+;//         Configure External Bus Behaviour for Static CS2 Area ---------------
+;//     <e> Configure External Bus Behaviour for Static CS2 Area
+EMC_STACS2_SETUP    EQU 0
+
+;//       <h> Static Memory Configuration Register (EMCStaticConfig2)
+;//         <i> Defines the configuration information for the static memory CS2
+;//         <o0.20> WP: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.8> EW: Extended wait enable
+;//         <o0.7> PB: Byte lane state
+;//           <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;//           <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;//         <o0.6> PC: Chip select polarity
+;//           <0=> Active LOW chip select
+;//           <1=> Active HIGH chip select
+;//         <o0.3> PM: Page mode enable
+;//         <o0.0..1> MW: Memory width
+;//           <0=> 8 bit
+;//           <1=> 16 bit
+;//           <2=> 32 bit
+;//       </h>
+EMC_STA_CFG2_Val    EQU 0x00000000
+
+;//       <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen2)
+;//         <i> Selects the delay from CS2 to write enable
+;//         <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWEN2_Val   EQU 0x00000000
+
+;//       <h> Static Memory Output Enable Delay register (EMCStaticWaitOen2)
+;//         <i> Selects the delay from CS2 or address change, whichever is later, to output enable
+;//         <o.0..3> WAITOEN: Wait output enable <0-15>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WOEN2_Val   EQU 0x00000000
+                                      
+;//       <h> Static Memory Read Delay Register (EMCStaticWaitRd2)
+;//         <i> Selects the delay from CS2 to a read access
+;//         <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WRD2_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage2)
+;//         <i> Selects the delay for asynchronous page mode sequential accesses for CS2
+;//         <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WPAGE2_Val  EQU 0x0000001F
+
+;//       <h> Static Memory Write Delay Register (EMCStaticWaitWr2)
+;//         <i> Selects the delay from CS2 to a write access
+;//         <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWR2_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn2)
+;//         <i> Selects the number of bus turnaround cycles for CS2
+;//         <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WTURN2_Val  EQU 0x0000000F
+
+;//     </e> End of Static Setup for Static CS2 Area
+
+;//         Configure External Bus Behaviour for Static CS3 Area ---------------
+;//     <e> Configure External Bus Behaviour for Static CS3 Area
+EMC_STACS3_SETUP    EQU 0
+
+;//       <h> Static Memory Configuration Register (EMCStaticConfig3)
+;//         <i> Defines the configuration information for the static memory CS3
+;//         <o0.20> WP: Write protect
+;//         <o0.19> B: Buffer enable
+;//         <o0.8> EW: Extended wait enable
+;//         <o0.7> PB: Byte lane state
+;//           <0=> For reads BLSn are HIGH, for writes BLSn are LOW
+;//           <1=> For reads BLSn are LOW, for writes BLSn are LOW
+;//         <o0.6> PC: Chip select polarity
+;//           <0=> Active LOW chip select
+;//           <1=> Active HIGH chip select
+;//         <o0.3> PM: Page mode enable
+;//         <o0.0..1> MW: Memory width
+;//           <0=> 8 bit
+;//           <1=> 16 bit
+;//           <2=> 32 bit
+;//       </h>
+EMC_STA_CFG3_Val    EQU 0x00000000
+
+;//       <h> Static Memory Write Enable Delay Register (EMCStaticWaitWen3)
+;//         <i> Selects the delay from CS3 to write enable
+;//         <o.0..3> WAITWEN: Wait write enable <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWEN3_Val   EQU 0x00000000
+
+;//       <h> Static Memory Output Enable Delay register (EMCStaticWaitOen3)
+;//         <i> Selects the delay from CS3 or address change, whichever is later, to output enable
+;//         <o.0..3> WAITOEN: Wait output enable <0-15>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WOEN3_Val   EQU 0x00000000
+                                      
+;//       <h> Static Memory Read Delay Register (EMCStaticWaitRd3)
+;//         <i> Selects the delay from CS3 to a read access
+;//         <o.0..4> WAITRD: Non-page mode read wait states or asynchronous page mode read first access wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WRD3_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Page Mode Read Delay Register (EMCStaticWaitPage3)
+;//         <i> Selects the delay for asynchronous page mode sequential accesses for CS3
+;//         <o.0..4> WAITPAGE: Asynchronous page mode read after the first read wait states <1-32> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WPAGE3_Val  EQU 0x0000001F
+
+;//       <h> Static Memory Write Delay Register (EMCStaticWaitWr3)
+;//         <i> Selects the delay from CS3 to a write access
+;//         <o.0..4> WAITWR: Write wait states <2-33> <#-2>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WWR3_Val    EQU 0x0000001F
+
+;//       <h> Static Memory Turn Round Delay Register (EMCStaticWaitTurn3)
+;//         <i> Selects the number of bus turnaround cycles for CS3
+;//         <o.0..4> WAITTURN: Bus turnaround cycles <1-16> <#-1>
+;//           <i> The delay is in CCLK cycles
+;//       </h>
+EMC_STA_WTURN3_Val  EQU 0x0000000F
+
+;//     </e> End of Static Setup for Static CS3 Area
+
+;//     <h> Static Memory Extended Wait Register (EMCStaticExtendedWait)
+;//       <i> Time long static memory read and write transfers
+;//       <o.0..9> EXTENDEDWAIT: Extended wait time out <0-1023>
+;//         <i> The delay is in (16 * CCLK) cycles
+;//     </h>
+EMC_STA_EXT_W_Val   EQU 0x00000000
+
+;//   </e> End of Static Setup
+
+;// </e> End of EMC Setup
+
+
+                PRESERVE8
+
+; Area Definition and Entry Point
+;  Startup Code must be linked first at Address at which it expects to run.
+
+                AREA    RESET, CODE, READONLY
+                ARM
+
+
+; Exception Vectors
+;  Mapped to Address 0.
+;  Absolute addressing mode must be used.
+;  Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors         LDR     PC, Reset_Addr         
+                LDR     PC, Undef_Addr
+                LDR     PC, SWI_Addr
+                LDR     PC, PAbt_Addr
+                LDR     PC, DAbt_Addr
+                NOP                            ; Reserved Vector 
+               	LDR     PC, IRQ_Addr
+                LDR     PC, FIQ_Addr
+
+Reset_Addr      DCD     Reset_Handler
+Undef_Addr      DCD     Undef_Handler
+SWI_Addr        DCD     SWI_Handler
+PAbt_Addr       DCD     PAbt_Handler
+DAbt_Addr       DCD     DAbt_Handler
+                DCD     0                      ; Reserved Address 
+IRQ_Addr        DCD     IRQ_Handler
+FIQ_Addr        DCD     FIQ_Handler
+
+Undef_Handler   B       Undef_Handler
+SWI_Handler     B       SWI_Handler
+PAbt_Handler    B       PAbt_Handler
+DAbt_Handler    B       DAbt_Handler
+FIQ_Handler     B       FIQ_Handler
+
+
+; Reset Handler
+
+                EXPORT  Reset_Handler
+Reset_Handler   
+
+
+; Clock Setup ------------------------------------------------------------------
+
+                IF      (:LNOT:(:DEF:NO_CLOCK_SETUP)):LAND:(CLOCK_SETUP != 0)
+                LDR     R0, =SCB_BASE
+                MOV     R1, #0xAA
+                MOV     R2, #0x55
+
+;  Configure and Enable PLL
+                LDR     R3, =SCS_Val          ; Enable main oscillator
+                STR     R3, [R0, #SCS_OFS] 
+
+                IF      (SCS_Val:AND:OSCEN) != 0  
+OSC_Loop        LDR     R3, [R0, #SCS_OFS]    ; Wait for main osc stabilize
+                ANDS    R3, R3, #OSCSTAT
+                BEQ     OSC_Loop
+                ENDIF
+
+                LDR     R3, =CLKSRCSEL_Val    ; Select PLL source clock
+                STR     R3, [R0, #CLKSRCSEL_OFS] 
+                LDR     R3, =PLLCFG_Val
+                STR     R3, [R0, #PLLCFG_OFS] 
+                STR     R1, [R0, #PLLFEED_OFS]
+                STR     R2, [R0, #PLLFEED_OFS]
+                MOV     R3, #PLLCON_PLLE
+                STR     R3, [R0, #PLLCON_OFS]
+                STR     R1, [R0, #PLLFEED_OFS]
+                STR     R2, [R0, #PLLFEED_OFS]
+
+                IF      (CLKSRCSEL_Val:AND:3) != 2
+;  Wait until PLL Locked (if source is not RTC oscillator)
+PLL_Loop        LDR     R3, [R0, #PLLSTAT_OFS]
+                ANDS    R3, R3, #PLLSTAT_PLOCK
+                BEQ     PLL_Loop
+                ELSE
+;  Wait at least 200 cycles (if source is RTC oscillator)
+                MOV     R3, #(200/4)
+PLL_Loop        SUBS    R3, R3, #1
+                BNE     PLL_Loop
+                ENDIF
+
+M_N_Lock        LDR     R3, [R0, #PLLSTAT_OFS]
+                LDR     R4, =(PLLSTAT_M:OR:PLLSTAT_N)
+                AND     R3, R3, R4
+                LDR     R4, =PLLCFG_Val
+                EORS    R3, R3, R4
+                BNE     M_N_Lock
+
+;  Setup CPU clock divider
+                MOV     R3, #CCLKCFG_Val
+                STR     R3, [R0, #CCLKCFG_OFS]
+
+;  Setup USB clock divider
+                LDR     R3, =USBCLKCFG_Val
+                STR     R3, [R0, #USBCLKCFG_OFS]
+
+;  Setup Peripheral Clock
+                LDR     R3, =PCLKSEL0_Val
+                STR     R3, [R0, #PCLKSEL0_OFS]
+                LDR     R3, =PCLKSEL1_Val
+                STR     R3, [R0, #PCLKSEL1_OFS]
+
+;  Switch to PLL Clock
+                MOV     R3, #(PLLCON_PLLE:OR:PLLCON_PLLC)
+                STR     R3, [R0, #PLLCON_OFS]
+                STR     R1, [R0, #PLLFEED_OFS]
+                STR     R2, [R0, #PLLFEED_OFS]
+                ENDIF   ; CLOCK_SETUP
+
+
+; Setup Memory Accelerator Module ----------------------------------------------
+
+                IF      MAM_SETUP != 0
+                LDR     R0, =MAM_BASE
+                MOV     R1, #MAMTIM_Val
+                STR     R1, [R0, #MAMTIM_OFS] 
+                MOV     R1, #MAMCR_Val
+                STR     R1, [R0, #MAMCR_OFS] 
+                ENDIF   ; MAM_SETUP
+
+
+; Setup External Memory Controller ---------------------------------------------
+
+                IF      (:LNOT:(:DEF:NO_EMC_SETUP)):LAND:(EMC_SETUP != 0)
+                LDR     R0, =EMC_BASE
+                LDR     R1, =SCB_BASE
+                LDR     R2, =PCB_BASE
+
+                LDR     R4, =EMC_PCONP_Const      ; Enable EMC
+                LDR     R3, [R1, #PCONP_OFS]
+                ORR     R4, R4, R3
+                STR     R4, [R1, #PCONP_OFS]
+
+                LDR     R4, =EMC_CTRL_Val
+                STR     R4, [R0, #EMC_CTRL_OFS]
+                LDR     R4, =EMC_CONFIG_Val
+                STR     R4, [R0, #EMC_CONFIG_OFS]
+
+;  Setup pin functions for External Bus functionality
+                LDR     R4, =EMC_PINSEL5_Val
+                STR     R4, [R2, #PINSEL5_OFS]
+                LDR     R4, =EMC_PINSEL6_Val
+                STR     R4, [R2, #PINSEL6_OFS]
+                LDR     R4, =EMC_PINSEL8_Val
+                STR     R4, [R2, #PINSEL8_OFS]
+                LDR     R4, =EMC_PINSEL9_Val
+                STR     R4, [R2, #PINSEL9_OFS]
+
+;  Setup Dynamic Memory Interface
+                IF      (EMC_DYNAMIC_SETUP != 0)
+
+                LDR     R4, =EMC_DYN_RP_Val
+                STR     R4, [R0, #EMC_DYN_RP_OFS]
+                LDR     R4, =EMC_DYN_RAS_Val
+                STR     R4, [R0, #EMC_DYN_RAS_OFS]
+                LDR     R4, =EMC_DYN_SREX_Val
+                STR     R4, [R0, #EMC_DYN_SREX_OFS]
+                LDR     R4, =EMC_DYN_APR_Val
+                STR     R4, [R0, #EMC_DYN_APR_OFS]
+                LDR     R4, =EMC_DYN_DAL_Val
+                STR     R4, [R0, #EMC_DYN_DAL_OFS]
+                LDR     R4, =EMC_DYN_WR_Val
+                STR     R4, [R0, #EMC_DYN_WR_OFS]
+                LDR     R4, =EMC_DYN_RC_Val
+                STR     R4, [R0, #EMC_DYN_RC_OFS]
+                LDR     R4, =EMC_DYN_RFC_Val
+                STR     R4, [R0, #EMC_DYN_RFC_OFS]
+                LDR     R4, =EMC_DYN_XSR_Val
+                STR     R4, [R0, #EMC_DYN_XSR_OFS]
+                LDR     R4, =EMC_DYN_RRD_Val
+                STR     R4, [R0, #EMC_DYN_RRD_OFS]
+                LDR     R4, =EMC_DYN_MRD_Val
+                STR     R4, [R0, #EMC_DYN_MRD_OFS]
+
+                LDR     R4, =EMC_DYN_RD_CFG_Val
+                STR     R4, [R0, #EMC_DYN_RD_CFG_OFS]
+
+                IF      (EMC_DYNCS0_SETUP != 0)
+                LDR     R4, =EMC_DYN_RASCAS0_Val
+                STR     R4, [R0, #EMC_DYN_RASCAS0_OFS]
+                LDR     R4, =EMC_DYN_CFG0_Val
+                MVN     R5, #BUFEN_Const
+                AND     R4, R4, R5
+                STR     R4, [R0, #EMC_DYN_CFG0_OFS]
+                ENDIF
+                IF      (EMC_DYNCS1_SETUP != 0)
+                LDR     R4, =EMC_DYN_RASCAS1_Val
+                STR     R4, [R0, #EMC_DYN_RASCAS1_OFS]
+                LDR     R4, =EMC_DYN_CFG1_Val
+                MVN     R5, =BUFEN_Const
+                AND     R4, R4, R5
+                STR     R4, [R0, #EMC_DYN_CFG1_OFS]
+                ENDIF
+                IF      (EMC_DYNCS2_SETUP != 0)
+                LDR     R4, =EMC_DYN_RASCAS2_Val
+                STR     R4, [R0, #EMC_DYN_RASCAS2_OFS]
+                LDR     R4, =EMC_DYN_CFG2_Val
+                MVN     R5, =BUFEN_Const
+                AND     R4, R4, R5
+                STR     R4, [R0, #EMC_DYN_CFG2_OFS]
+                ENDIF
+                IF      (EMC_DYNCS3_SETUP != 0)
+                LDR     R4, =EMC_DYN_RASCAS3_Val
+                STR     R4, [R0, #EMC_DYN_RASCAS3_OFS]
+                LDR     R4, =EMC_DYN_CFG3_Val
+                MVN     R5, =BUFEN_Const
+                AND     R4, R4, R5
+                STR     R4, [R0, #EMC_DYN_CFG3_OFS]
+                ENDIF
+
+                LDR     R6, =1440000              ; Number of cycles to delay
+Wait_0          SUBS    R6, R6, #1                ; Delay ~100 ms proc clk 57.6 MHz
+                BNE     Wait_0                    ; BNE (3 cyc) + SUBS (1 cyc) = 4 cyc
+
+                LDR     R4, =(NOP_CMD:OR:0x03)    ; Write NOP Command
+                STR     R4, [R0, #EMC_DYN_CTRL_OFS]
+
+                LDR     R6, =2880000              ; Number of cycles to delay
+Wait_1          SUBS    R6, R6, #1                ; Delay ~200 ms proc clk 57.6 MHz
+                BNE     Wait_1
+
+                LDR     R4, =(PALL_CMD:OR:0x03)   ; Write Precharge All Command
+                STR     R4, [R0, #EMC_DYN_CTRL_OFS]
+  
+                MOV     R4, #2
+                STR     R4, [R0, #EMC_DYN_RFSH_OFS]
+
+                MOV     R6, #64                   ; Number of cycles to delay
+Wait_2          SUBS    R6, R6, #1                ; Delay
+                BNE     Wait_2
+
+                LDR     R4, =EMC_DYN_RFSH_Val
+                STR     R4, [R0, #EMC_DYN_RFSH_OFS]
+
+                LDR     R4, =(MODE_CMD:OR:0x03)   ; Write MODE Command
+                STR     R4, [R0, #EMC_DYN_CTRL_OFS]
+    
+                ; Dummy read
+                IF      (EMC_DYNCS0_SETUP != 0)
+                LDR     R4, =DYN_MEM0_BASE
+                MOV     R5, #(0x33 << 12)
+                ADD     R4, R4, R5
+                LDR     R4, [R4, #0]
+                ENDIF
+                IF      (EMC_DYNCS1_SETUP != 0)
+                LDR     R4, =DYN_MEM1_BASE
+                MOV     R5, #(0x33 << 12)
+                ADD     R4, R4, R5
+                LDR     R4, [R4, #0]
+                ENDIF
+                IF      (EMC_DYNCS2_SETUP != 0)
+                LDR     R4, =DYN_MEM2_BASE
+                MOV     R5, #(0x33 << 12)
+                ADD     R4, R4, R5
+                LDR     R4, [R4, #0]
+                ENDIF
+                IF      (EMC_DYNCS3_SETUP != 0)
+                LDR     R4, =DYN_MEM3_BASE
+                MOV     R5, #(0x33 << 12)
+                ADD     R4, R4, R5
+                LDR     R4, [R4, #0]
+                ENDIF
+
+                LDR     R4, =NORMAL_CMD           ; Write NORMAL Command
+                STR     R4, [R0, #EMC_DYN_CTRL_OFS]
+
+                ; Enable buffer if requested by settings
+                IF      (EMC_DYNCS0_SETUP != 0):LAND:((EMC_DYN_CFG0_Val:AND:BUFEN_Const) != 0)
+                LDR     R4, =EMC_DYN_CFG0_Val
+                STR     R4, [R0, #EMC_DYN_CFG0_OFS]
+                ENDIF
+                IF      (EMC_DYNCS1_SETUP != 0):LAND:((EMC_DYN_CFG1_Val:AND:BUFEN_Const) != 0)
+                LDR     R4, =EMC_DYN_CFG1_Val
+                STR     R4, [R0, #EMC_DYN_CFG1_OFS]
+                ENDIF
+                IF      (EMC_DYNCS2_SETUP != 0):LAND:((EMC_DYN_CFG2_Val:AND:BUFEN_Const) != 0)
+                LDR     R4, =EMC_DYN_CFG2_Val
+                STR     R4, [R0, #EMC_DYN_CFG2_OFS]
+                ENDIF
+                IF      (EMC_DYNCS3_SETUP != 0):LAND:((EMC_DYN_CFG3_Val:AND:BUFEN_Const) != 0)
+                LDR     R4, =EMC_DYN_CFG3_Val
+                STR     R4, [R0, #EMC_DYN_CFG3_OFS]
+                ENDIF
+
+                LDR     R6, =14400                ; Number of cycles to delay
+Wait_3          SUBS    R6, R6, #1                ; Delay ~1 ms @ proc clk 57.6 MHz
+                BNE     Wait_3
+
+                ENDIF		; EMC_DYNAMIC_SETUP
+
+;  Setup Static Memory Interface
+                IF      (EMC_STATIC_SETUP != 0)
+
+                LDR     R6, =1440000              ; Number of cycles to delay
+Wait_4          SUBS    R6, R6, #1                ; Delay ~100 ms @ proc clk 57.6 MHz
+                BNE     Wait_4
+
+                IF      (EMC_STACS0_SETUP != 0)
+                LDR     R4, =EMC_STA_CFG0_Val
+                STR     R4, [R0, #EMC_STA_CFG0_OFS]
+                LDR     R4, =EMC_STA_WWEN0_Val
+                STR     R4, [R0, #EMC_STA_WWEN0_OFS]
+                LDR     R4, =EMC_STA_WOEN0_Val
+                STR     R4, [R0, #EMC_STA_WOEN0_OFS]
+                LDR     R4, =EMC_STA_WRD0_Val
+                STR     R4, [R0, #EMC_STA_WRD0_OFS]
+                LDR     R4, =EMC_STA_WPAGE0_Val
+                STR     R4, [R0, #EMC_STA_WPAGE0_OFS]
+                LDR     R4, =EMC_STA_WWR0_Val
+                STR     R4, [R0, #EMC_STA_WWR0_OFS]
+                LDR     R4, =EMC_STA_WTURN0_Val
+                STR     R4, [R0, #EMC_STA_WTURN0_OFS]
+                ENDIF
+
+                IF      (EMC_STACS1_SETUP != 0)
+                LDR     R4, =EMC_STA_CFG1_Val
+                STR     R4, [R0, #EMC_STA_CFG1_OFS]
+                LDR     R4, =EMC_STA_WWEN1_Val
+                STR     R4, [R0, #EMC_STA_WWEN1_OFS]
+                LDR     R4, =EMC_STA_WOEN1_Val
+                STR     R4, [R0, #EMC_STA_WOEN1_OFS]
+                LDR     R4, =EMC_STA_WRD1_Val
+                STR     R4, [R0, #EMC_STA_WRD1_OFS]
+                LDR     R4, =EMC_STA_WPAGE1_Val
+                STR     R4, [R0, #EMC_STA_WPAGE1_OFS]
+                LDR     R4, =EMC_STA_WWR1_Val
+                STR     R4, [R0, #EMC_STA_WWR1_OFS]
+                LDR     R4, =EMC_STA_WTURN1_Val
+                STR     R4, [R0, #EMC_STA_WTURN1_OFS]
+                ENDIF
+
+                IF      (EMC_STACS2_SETUP != 0)
+                LDR     R4, =EMC_STA_CFG2_Val
+                STR     R4, [R0, #EMC_STA_CFG2_OFS]
+                LDR     R4, =EMC_STA_WWEN2_Val
+                STR     R4, [R0, #EMC_STA_WWEN2_OFS]
+                LDR     R4, =EMC_STA_WOEN2_Val
+                STR     R4, [R0, #EMC_STA_WOEN2_OFS]
+                LDR     R4, =EMC_STA_WRD2_Val
+                STR     R4, [R0, #EMC_STA_WRD2_OFS]
+                LDR     R4, =EMC_STA_WPAGE2_Val
+                STR     R4, [R0, #EMC_STA_WPAGE2_OFS]
+                LDR     R4, =EMC_STA_WWR2_Val
+                STR     R4, [R0, #EMC_STA_WWR2_OFS]
+                LDR     R4, =EMC_STA_WTURN2_Val
+                STR     R4, [R0, #EMC_STA_WTURN2_OFS]
+                ENDIF
+
+                IF      (EMC_STACS3_SETUP != 0)
+                LDR     R4, =EMC_STA_CFG3_Val
+                STR     R4, [R0, #EMC_STA_CFG3_OFS]
+                LDR     R4, =EMC_STA_WWEN3_Val
+                STR     R4, [R0, #EMC_STA_WWEN3_OFS]
+                LDR     R4, =EMC_STA_WOEN3_Val
+                STR     R4, [R0, #EMC_STA_WOEN3_OFS]
+                LDR     R4, =EMC_STA_WRD3_Val
+                STR     R4, [R0, #EMC_STA_WRD3_OFS]
+                LDR     R4, =EMC_STA_WPAGE3_Val
+                STR     R4, [R0, #EMC_STA_WPAGE3_OFS]
+                LDR     R4, =EMC_STA_WWR3_Val
+                STR     R4, [R0, #EMC_STA_WWR3_OFS]
+                LDR     R4, =EMC_STA_WTURN3_Val
+                STR     R4, [R0, #EMC_STA_WTURN3_OFS]
+                ENDIF
+
+                LDR     R6, =144000               ; Number of cycles to delay
+Wait_5          SUBS    R6, R6, #1                ; Delay ~10 ms @ proc clk 57.6 MHz
+                BNE     Wait_5
+
+                LDR     R4, =EMC_STA_EXT_W_Val
+                LDR     R5, =EMC_STA_EXT_W_OFS
+                ADD     R5, R5, R0
+                STR     R4, [R5, #0]
+
+                ENDIF   ; EMC_STATIC_SETUP 
+
+                ENDIF   ; EMC_SETUP
+
+
+; Copy Exception Vectors to Internal RAM ---------------------------------------
+
+                IF      :DEF:RAM_INTVEC
+                ADR     R8, Vectors         ; Source
+                LDR     R9, =RAM_BASE       ; Destination
+                LDMIA   R8!, {R0-R7}        ; Load Vectors 
+                STMIA   R9!, {R0-R7}        ; Store Vectors 
+                LDMIA   R8!, {R0-R7}        ; Load Handler Addresses 
+                STMIA   R9!, {R0-R7}        ; Store Handler Addresses
+                ENDIF
+
+
+; Memory Mapping (when Interrupt Vectors are in RAM) ---------------------------
+
+MEMMAP          EQU     0xE01FC040      ; Memory Mapping Control
+                IF      :DEF:REMAP
+                LDR     R0, =MEMMAP
+                IF      :DEF:EXTMEM_MODE
+                MOV     R1, #3
+                ELIF    :DEF:RAM_MODE
+                MOV     R1, #2
+                ELSE
+                MOV     R1, #1
+                ENDIF
+                STR     R1, [R0]
+                ENDIF
+
+
+; Setup Stack for each mode ----------------------------------------------------
+
+                LDR     R0, =Stack_Top
+
+;  Enter Undefined Instruction Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #UND_Stack_Size
+
+;  Enter Abort Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #ABT_Stack_Size
+
+;  Enter FIQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #FIQ_Stack_Size
+
+;  Enter IRQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #IRQ_Stack_Size
+
+;  Enter Supervisor Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #SVC_Stack_Size
+
+                IF      :DEF:__MICROLIB
+                EXPORT __initial_sp
+                ELSE
+                ENDIF
+
+; Enter the C code -------------------------------------------------------------
+
+                IMPORT  __main
+                LDR     R0, =__main
+                BX      R0
+
+				IMPORT rt_interrupt_enter
+				IMPORT rt_interrupt_leave
+				IMPORT rt_thread_switch_interrput_flag
+				IMPORT rt_interrupt_from_thread
+				IMPORT rt_interrupt_to_thread
+				IMPORT rt_hw_trap_irq
+
+IRQ_Handler		PROC
+				EXPORT IRQ_Handler
+				STMFD	sp!, {r0-r12,lr}
+				BL	rt_interrupt_enter
+				BL	rt_hw_trap_irq
+				BL	rt_interrupt_leave
+
+				; if rt_thread_switch_interrput_flag set, jump to
+				; rt_hw_context_switch_interrupt_do and don't return
+				LDR	r0, =rt_thread_switch_interrput_flag
+				LDR	r1, [r0]
+				CMP	r1, #1
+				BEQ	rt_hw_context_switch_interrupt_do
+
+				LDMFD	sp!, {r0-r12,lr}
+				SUBS	pc, lr, #4
+				ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do	PROC
+				EXPORT rt_hw_context_switch_interrupt_do
+				MOV		r1,  #0			; clear flag
+				STR		r1,  [r0]
+
+				LDMFD	sp!, {r0-r12,lr}; reload saved registers
+				STMFD	sp!, {r0-r3}	; save r0-r3
+				MOV		r1,  sp
+				ADD		sp,  sp, #16	; restore sp
+				SUB		r2,  lr, #4		; save old task's pc to r2
+
+				MRS		r3,  spsr		; get cpsr of interrupt thread
+
+				; switch to SVC mode and no interrupt
+                MSR     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+				STMFD	sp!, {r2}		; push old task's pc
+				STMFD	sp!, {r4-r12,lr}; push old task's lr,r12-r4
+				MOV		r4,  r1			; Special optimised code below
+				MOV		r5,  r3
+				LDMFD	r4!, {r0-r3}
+				STMFD	sp!, {r0-r3}	; push old task's r3-r0
+				STMFD	sp!, {r5}		; push old task's cpsr
+				MRS		r4,  spsr
+				STMFD	sp!, {r4}		; push old task's spsr
+
+				LDR		r4,  =rt_interrupt_from_thread
+				LDR		r5,  [r4]
+				STR		sp,  [r5]		; store sp in preempted tasks's TCB
+
+				LDR		r6,  =rt_interrupt_to_thread
+				LDR		r6,  [r6]
+				LDR		sp,  [r6]		; get new task's stack pointer
+			
+				LDMFD	sp!, {r4}		; pop new task's spsr
+				MSR		spsr_cxsf, r4
+				LDMFD	sp!, {r4}		; pop new task's psr
+				MSR		cpsr_cxsf, r4
+
+				LDMFD	sp!, {r0-r12,lr,pc}	; pop new task's r0-r12,lr & pc
+				ENDP
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+; User Initial Stack & Heap
+                AREA    |.text|, CODE, READONLY
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + USR_Stack_Size)
+                LDR     R2, = (Heap_Mem +      Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDIF
+
+
+                END

+ 132 - 0
libcpu/arm/lpc24xx/trap.c

@@ -0,0 +1,132 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2008-12-11     XuXinming    first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "LPC24xx.h"
+
+//#define BSP_INT_DEBUG
+
+/**
+ * @addtogroup LPC2478
+ */
+/*@{*/
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+	rt_kprintf("Execption:\n");
+	rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+	rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+	rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+	rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+	rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+	rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+    rt_kprintf("undefined instruction\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+    rt_kprintf("software interrupt\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+    rt_kprintf("prefetch abort\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{	
+    rt_kprintf("Data Abort ");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+    rt_kprintf("not used\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+extern rt_isr_handler_t isr_table[];
+void rt_hw_trap_irq()
+{
+	rt_isr_handler_t isr_func;
+	
+	isr_func = (rt_isr_handler_t) VICVectAddr;
+	isr_func(0);
+}
+
+void rt_hw_trap_fiq()
+{	
+    rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/

+ 99 - 0
libcpu/arm/s3c44b0/context_gcc.S

@@ -0,0 +1,99 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ */
+
+/*!
+ * \addtogroup S3C44B0
+ */
+/*@{*/
+
+#define NOINT			0xc0
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	ldr	sp, [r1]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr	sp, [r0]		@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr r2, =rt_thread_switch_interrput_flag
+	ldr r3, [r2]
+	cmp r3, #1
+	beq _reswitch
+	mov r3, #1				@ set rt_thread_switch_interrput_flag to 1
+	str r3, [r2]
+	ldr r2, =rt_interrupt_from_thread	@ set rt_interrupt_from_thread
+	str r0, [r2]
+_reswitch:
+	ldr r2, =rt_interrupt_to_thread		@ set rt_interrupt_to_thread
+	str r1, [r2]
+	mov pc, lr

+ 107 - 0
libcpu/arm/s3c44b0/context_rvds.s

@@ -0,0 +1,107 @@
+;/*
+; * File      : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date           Author       Notes
+; * 2009-01-20     Bernard      first version
+; */
+
+NOINT	EQU		0xc0	; disable interrupt in psr
+
+	AREA |.text|, CODE, READONLY, ALIGN=2
+	ARM
+	REQUIRE8
+	PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable	PROC
+	EXPORT rt_hw_interrupt_disable
+	MRS r0, cpsr
+	ORR r1, r0, #NOINT
+	MSR cpsr_c, r1
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable	PROC
+	EXPORT rt_hw_interrupt_enable
+	MSR cpsr_c, r0
+	BX	lr
+	ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch	PROC
+	EXPORT rt_hw_context_switch
+	STMFD	sp!, {lr}			; push pc (lr should be pushed in place of PC)
+	STMFD	sp!, {r0-r12, lr}	; push lr & register file
+
+	MRS		r4, cpsr
+	STMFD	sp!, {r4}			; push cpsr
+	MRS		r4, spsr
+	STMFD	sp!, {r4}			; push spsr
+
+	STR	sp, [r0]				; store sp in preempted tasks TCB
+	LDR	sp, [r1]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to	PROC
+	EXPORT rt_hw_context_switch_to
+	LDR	sp, [r0]				; get new task stack pointer
+
+	LDMFD	sp!, {r4}			; pop new task spsr
+	MSR	spsr_cxsf, r4
+	LDMFD	sp!, {r4}			; pop new task cpsr
+	MSR	cpsr_cxsf, r4
+
+	LDMFD	sp!, {r0-r12, lr, pc}	; pop new task r0-r12, lr & pc
+	ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+	IMPORT rt_thread_switch_interrput_flag
+	IMPORT rt_interrupt_from_thread
+	IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt	PROC
+	EXPORT rt_hw_context_switch_interrupt
+	LDR r2, =rt_thread_switch_interrput_flag
+	LDR r3, [r2]
+	CMP r3, #1
+	BEQ _reswitch
+	MOV r3, #1							; set rt_thread_switch_interrput_flag to 1
+	STR r3, [r2]
+	LDR r2, =rt_interrupt_from_thread	; set rt_interrupt_from_thread
+	STR r0, [r2]
+_reswitch
+	LDR r2, =rt_interrupt_to_thread		; set rt_interrupt_to_thread
+	STR r1, [r2]
+	BX	lr
+	ENDP
+
+	END

+ 122 - 0
libcpu/arm/s3c44b0/cpu.c

@@ -0,0 +1,122 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ */
+
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * This function will enable I-Cache of CPU
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+	rt_base_t reg;
+
+	volatile int i;
+	/* flush cycle */
+	for(i = 0x10002000; i < 0x10004800; i+=16)
+	{
+		*((int *)i)=0x0;
+	}
+
+	/*
+	 *	Init cache
+	 *	Non-cacheable area (everything outside RAM)
+	 *	0x0000:0000 - 0x0C00:0000
+	 */
+	NCACHBE0 = 0xC0000000;
+	NCACHBE1 = 0x00000000;
+
+	/*
+		Enable chache
+	*/
+	reg = SYSCFG;
+	reg |= 0x00000006; /* 8kB */
+	SYSCFG = reg;
+}
+
+/**
+ * This function will disable I-Cache of CPU
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+	rt_base_t reg;
+
+	reg = SYSCFG;
+	reg &= ~0x00000006; /* 8kB */
+	SYSCFG = reg;
+}
+
+/**
+ * this function will get the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+	return 0;
+}
+
+/**
+ * this function will enable D-Cache of CPU
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+	rt_hw_cpu_icache_enable();
+}
+
+/**
+ * this function will disable D-Cache of CPU
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+	rt_hw_cpu_icache_disable();
+}
+
+/**
+ * this function will get the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+	return rt_hw_cpu_icache_status();
+}
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/

+ 148 - 0
libcpu/arm/s3c44b0/interrupt.c

@@ -0,0 +1,148 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ * 2006-09-15     Bernard      add interrupt bank 0..3 for more effective 
+ *                             in irq trap
+ */
+
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+#define MAX_HANDLERS	26
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_isr_handler_t isr_table[MAX_HANDLERS];
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+unsigned char interrupt_bank0[256];
+unsigned char interrupt_bank1[256];
+unsigned char interrupt_bank2[256];
+unsigned char interrupt_bank3[256];
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+void rt_hw_interrupt_handle(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	register int i;
+
+	/* all interrupt disabled include global bit */
+	INTMSK = 0x07ffffff;
+	
+	/* clear pending register */
+   	I_ISPC = 0x03ffffff;
+   	
+	/* non-vector mode IRQ enable */
+	INTCON = 0x5;
+	
+	/* all IRQ mode */
+	INTMOD = 0x0;
+
+	/* init exceptions table */
+	for(i=0; i<MAX_HANDLERS; i++)
+	{
+		isr_table[i] = rt_hw_interrupt_handle;
+	}
+
+	for ( i = 0; i < 256; i++)
+	{
+		interrupt_bank0[i] = 0;
+		interrupt_bank1[i] = 0;
+		interrupt_bank2[i] = 0;
+		interrupt_bank3[i] = 0;
+	}
+
+	/* setup interrupt bank table */
+	interrupt_bank0[1]	= 0;
+	interrupt_bank0[2]	= 1;
+	interrupt_bank0[4]	= 2;
+	interrupt_bank0[8]	= 3;
+	interrupt_bank0[16]	= 4;
+	interrupt_bank0[32]	= 5;
+	interrupt_bank0[64]	= 6;
+	interrupt_bank0[128]= 7;
+
+	interrupt_bank1[1]	= 8;
+	interrupt_bank1[2]	= 9;
+	interrupt_bank1[4]	= 10;
+	interrupt_bank1[8]	= 11;
+	interrupt_bank1[16]	= 12;
+	interrupt_bank1[32]	= 13;
+	interrupt_bank1[64]	= 14;
+	interrupt_bank1[128]= 15;
+
+	interrupt_bank2[1]	= 16;
+	interrupt_bank2[2]	= 17;
+	interrupt_bank2[4]	= 18;
+	interrupt_bank2[8]	= 19;
+	interrupt_bank2[16]	= 20;
+	interrupt_bank2[32]	= 21;
+	interrupt_bank2[64]	= 22;
+	interrupt_bank2[128]= 23;
+
+	interrupt_bank3[1]	= 24;
+	interrupt_bank3[2]	= 25;
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	INTMSK |= 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	INTMSK &= ~(1 << vector);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	if(vector < MAX_HANDLERS)
+	{
+		if (old_handler != RT_NULL) *old_handler = isr_table[vector];
+		if (new_handler != RT_NULL) isr_table[vector] = new_handler;
+	}
+}
+
+/*@}*/

+ 346 - 0
libcpu/arm/s3c44b0/s3c44b0.h

@@ -0,0 +1,346 @@
+/*
+ * File      : s3c45b0.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ * 2006-09-16     Bernard      modify according to code style
+ */
+
+#ifndef __S3C44B0_H__
+#define __S3C44B0_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/*------------------------------------------------------------------------
+ *	  ASIC Address Definition
+ *----------------------------------------------------------------------*/
+#define S3C_REG		*(volatile unsigned int *)
+#define S3C_REGW	*(volatile unsigned short *)
+#define S3C_REGB	*(volatile unsigned char *)
+
+/* System */
+#define SYSCFG		(S3C_REG(0x1c00000))
+
+/* Cache */
+#define NCACHBE0	(S3C_REG(0x1c00004))
+#define NCACHBE1	(S3C_REG(0x1c00008))
+
+/* Bus control */
+#define SBUSCON		(S3C_REG(0x1c40000))
+
+/* Memory control */
+#define BWSCON		(S3C_REG(0x1c80000))
+#define BANKCON0	(S3C_REG(0x1c80004))
+#define BANKCON1	(S3C_REG(0x1c80008))
+#define BANKCON2	(S3C_REG(0x1c8000c))
+#define BANKCON3	(S3C_REG(0x1c80010))
+#define BANKCON4	(S3C_REG(0x1c80014))
+#define BANKCON5	(S3C_REG(0x1c80018))
+#define BANKCON6	(S3C_REG(0x1c8001c))
+#define BANKCON7	(S3C_REG(0x1c80020))
+#define REFRESH		(S3C_REG(0x1c80024))
+#define BANKSIZE	(S3C_REG(0x1c80028))
+#define MRSRB6		(S3C_REG(0x1c8002c))
+#define MRSRB7		(S3C_REG(0x1c80030))
+
+/* UART */
+#define ULCON0		(S3C_REG(0x1d00000))
+#define ULCON1		(S3C_REG(0x1d04000))
+#define UCON0		(S3C_REG(0x1d00004))
+#define UCON1		(S3C_REG(0x1d04004))
+#define UFCON0		(S3C_REG(0x1d00008))
+#define UFCON1		(S3C_REG(0x1d04008))
+#define UMCON0		(S3C_REG(0x1d0000c))
+#define UMCON1		(S3C_REG(0x1d0400c))
+#define UTRSTAT0	(S3C_REG(0x1d00010))
+#define UTRSTAT1	(S3C_REG(0x1d04010))
+#define UERSTAT0	(S3C_REG(0x1d00014))
+#define UERSTAT1	(S3C_REG(0x1d04014))
+#define UFSTAT0		(S3C_REG(0x1d00018))
+#define UFSTAT1		(S3C_REG(0x1d04018))
+#define UMSTAT0		(S3C_REG(0x1d0001c))
+#define UMSTAT1		(S3C_REG(0x1d0401c))
+#define UBRDIV0		(S3C_REG(0x1d00028))
+#define UBRDIV1		(S3C_REG(0x1d04028))
+
+#define UTXH0		(S3C_REGB(0x1d00020))
+#define UTXH1		(S3C_REGB(0x1d04020))
+#define URXH0		(S3C_REGB(0x1d00024))
+#define URXH1		(S3C_REGB(0x1d04024))
+
+/* SIO */
+#define SIOCON		(S3C_REG(0x1d14000))
+#define SIODAT		(S3C_REG(0x1d14004))
+#define SBRDR		(S3C_REG(0x1d14008))
+#define IVTCNT		(S3C_REG(0x1d1400c))
+#define DCNTZ		(S3C_REG(0x1d14010))
+
+/* IIS */
+#define IISCON		(S3C_REG(0x1d18000))
+#define IISMOD		(S3C_REG(0x1d18004))
+#define IISPSR		(S3C_REG(0x1d18008))
+#define IISFCON		(S3C_REG(0x1d1800c))
+
+#define IISFIF		(S3C_REQW(0x1d18010))
+
+/* I/O Port */
+#define PCONA		(S3C_REG(0x1d20000))
+#define PDATA		(S3C_REG(0x1d20004))
+
+#define PCONB		(S3C_REG(0x1d20008))
+#define PDATB		(S3C_REG(0x1d2000c))
+
+#define PCONC		(S3C_REG(0x1d20010))
+#define PDATC		(S3C_REG(0x1d20014))
+#define PUPC		(S3C_REG(0x1d20018))
+
+#define PCOND		(S3C_REG(0x1d2001c))
+#define PDATD		(S3C_REG(0x1d20020))
+#define PUPD		(S3C_REG(0x1d20024))
+
+#define PCONE		(S3C_REG(0x1d20028))
+#define PDATE		(S3C_REG(0x1d2002c))
+#define PUPE		(S3C_REG(0x1d20030))
+
+#define PCONF		(S3C_REG(0x1d20034))
+#define PDATF		(S3C_REG(0x1d20038))
+#define PUPF		(S3C_REG(0x1d2003c))
+
+#define PCONG		(S3C_REG(0x1d20040))
+#define PDATG		(S3C_REG(0x1d20044))
+#define PUPG		(S3C_REG(0x1d20048))
+
+#define SPUCR		(S3C_REG(0x1d2004c))
+#define EXTINT		(S3C_REG(0x1d20050))
+#define EXTINTPND	(S3C_REG(0x1d20054))
+
+/* Watchdog */
+#define WTCON		(S3C_REG(0x1d30000))
+#define WTDAT		(S3C_REG(0x1d30004))
+#define WTCNT		(S3C_REG(0x1d30008))
+
+/* ADC */
+#define ADCCON		(S3C_REG(0x1d40000))
+#define ADCPSR		(S3C_REG(0x1d40004))
+#define ADCDAT		(S3C_REG(0x1d40008))
+
+/* Timer */
+#define TCFG0		(S3C_REG(0x1d50000))
+#define TCFG1		(S3C_REG(0x1d50004))
+#define TCON		(S3C_REG(0x1d50008))
+
+#define TCNTB0		(S3C_REG(0x1d5000c))
+#define TCMPB0		(S3C_REG(0x1d50010))
+#define TCNTO0		(S3C_REG(0x1d50014))
+
+#define TCNTB1		(S3C_REG(0x1d50018))
+#define TCMPB1		(S3C_REG(0x1d5001c))
+#define TCNTO1		(S3C_REG(0x1d50020))
+
+#define TCNTB2		(S3C_REG(0x1d50024))
+#define TCMPB2		(S3C_REG(0x1d50028))
+#define TCNTO2		(S3C_REG(0x1d5002c))
+
+#define TCNTB3		(S3C_REG(0x1d50030))
+#define TCMPB3		(S3C_REG(0x1d50034))
+#define TCNTO3		(S3C_REG(0x1d50038))
+
+#define TCNTB4		(S3C_REG(0x1d5003c))
+#define TCMPB4		(S3C_REG(0x1d50040))
+#define TCNTO4		(S3C_REG(0x1d50044))
+
+#define TCNTB5		(S3C_REG(0x1d50048))
+#define TCNTO5		(S3C_REG(0x1d5004c))
+
+/* IIC */
+#define IICCON		(S3C_REG(0x1d60000))
+#define IICSTAT    	(S3C_REG(0x1d60004))
+#define IICADD     	(S3C_REG(0x1d60008))
+#define IICDS		(S3C_REG(0x1d6000c))
+
+/* RTC */
+#define RTCCON		(S3C_REGB(0x1d70040)
+#define RTCALM		(S3C_REGB(0x1d70050)
+#define ALMSEC		(S3C_REGB(0x1d70054)
+#define ALMMIN		(S3C_REGB(0x1d70058)
+#define ALMHOUR		(S3C_REGB(0x1d7005c)
+#define ALMDAY		(S3C_REGB(0x1d70060)
+#define ALMMON		(S3C_REGB(0x1d70064)
+#define ALMYEAR		(S3C_REGB(0x1d70068)
+#define RTCRST		(S3C_REGB(0x1d7006c)
+#define BCDSEC		(S3C_REGB(0x1d70070)
+#define BCDMIN		(S3C_REGB(0x1d70074)
+#define BCDHOUR		(S3C_REGB(0x1d70078)
+#define BCDDAY		(S3C_REGB(0x1d7007c)
+#define BCDDATE		(S3C_REGB(0x1d70080)
+#define BCDMON		(S3C_REGB(0x1d70084)
+#define BCDYEAR		(S3C_REGB(0x1d70088)
+#define TICINT		(S3C_REGB(0x1d7008c)
+
+/* Clock & Power management */
+#define PLLCON		(S3C_REG(0x1d80000))
+#define CLKCON		(S3C_REG(0x1d80004))
+#define CLKSLOW		(S3C_REG(0x1d80008))
+#define LOCKTIME	(S3C_REG(0x1d8000c))
+
+/* Interrupt */
+#define INTCON		(S3C_REG(0x1e00000))
+#define INTPND		(S3C_REG(0x1e00004))
+#define INTMOD		(S3C_REG(0x1e00008))
+#define INTMSK		(S3C_REG(0x1e0000c))
+
+#define I_PSLV		(S3C_REG(0x1e00010))
+#define I_PMST		(S3C_REG(0x1e00014))
+#define I_CSLV		(S3C_REG(0x1e00018))
+#define I_CMST		(S3C_REG(0x1e0001c))
+#define I_ISPR		(S3C_REG(0x1e00020))
+#define I_ISPC		(S3C_REG(0x1e00024))
+
+#define F_ISPR		(S3C_REG(0x1e00038))
+#define F_ISPC		(S3C_REG(0x1e0003c))
+
+/********************************/
+/* LCD Controller Registers     */
+/********************************/
+#define LCDCON1		(S3C_REG(0x300000))
+#define LCDCON2		(S3C_REG(0x300004))
+#define LCDSADDR1	(S3C_REG(0x300008))
+#define LCDSADDR2	(S3C_REG(0x30000c))
+#define LCDSADDR3	(S3C_REG(0x300010))
+#define REDLUT		(S3C_REG(0x300014))
+#define GREENLUT	(S3C_REG(0x300018))
+#define BLUELUT		(S3C_REG(0x30001c))
+#define DP1_2		(S3C_REG(0x300020))
+#define DP4_7		(S3C_REG(0x300024))
+#define DP3_5		(S3C_REG(0x300028))
+#define DP2_3		(S3C_REG(0x30002c))
+#define DP5_7		(S3C_REG(0x300030))
+#define DP3_4		(S3C_REG(0x300034))
+#define DP4_5		(S3C_REG(0x300038))
+#define DP6_7		(S3C_REG(0x30003c))
+#define LCDCON3		(S3C_REG(0x300040))
+#define DITHMODE	(S3C_REG(0x300044))
+
+/* ZDMA0 */
+#define ZDCON0		(S3C_REG(0x1e80000))
+#define ZDISRC0		(S3C_REG(0x1e80004))
+#define ZDIDES0		(S3C_REG(0x1e80008))
+#define ZDICNT0		(S3C_REG(0x1e8000c))
+#define ZDCSRC0		(S3C_REG(0x1e80010))
+#define ZDCDES0		(S3C_REG(0x1e80014))
+#define ZDCCNT0		(S3C_REG(0x1e80018))
+
+/* ZDMA1 */
+#define ZDCON1		(S3C_REG(0x1e80020))
+#define ZDISRC1		(S3C_REG(0x1e80024))
+#define ZDIDES1		(S3C_REG(0x1e80028))
+#define ZDICNT1		(S3C_REG(0x1e8002c))
+#define ZDCSRC1		(S3C_REG(0x1e80030))
+#define ZDCDES1		(S3C_REG(0x1e80034))
+#define ZDCCNT1		(S3C_REG(0x1e80038))
+
+/* BDMA0 */
+#define BDCON0		(S3C_REG(0x1f80000))
+#define BDISRC0		(S3C_REG(0x1f80004))
+#define BDIDES0		(S3C_REG(0x1f80008))
+#define BDICNT0		(S3C_REG(0x1f8000c))
+#define BDCSRC0		(S3C_REG(0x1f80010))
+#define BDCDES0		(S3C_REG(0x1f80014))
+#define BDCCNT0		(S3C_REG(0x1f80018))
+
+/* BDMA1 */
+#define BDCON1		(S3C_REG(0x1f80020))
+#define BDISRC1		(S3C_REG(0x1f80024))
+#define BDIDES1		(S3C_REG(0x1f80028))
+#define BDICNT1		(S3C_REG(0x1f8002c))
+#define BDCSRC1		(S3C_REG(0x1f80030))
+#define BDCDES1		(S3C_REG(0x1f80034))
+#define BDCCNT1		(S3C_REG(0x1f80038))
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE	0x10		/* User Mode(USR) */
+#define FIQMODE		0x11		/* Fast Interrupt Mode (FIQ) */
+#define IRQMODE		0x12		/* Interrupt Mode (IRQ) */
+#define SVCMODE		0x13		/* Supervisor Mode (SVC) */
+#define ABORTMODE	0x17		/* Abort Mode(ABT) */
+#define UNDEFMODE	0x1b		/* Undefine Mode(UDF) */
+#define MODEMASK	0x1f		/* Processor Mode Mask */
+#define NOINT		0xc0
+
+/*****************************/
+/* INT Define                */
+/*****************************/
+#define INT_ADC		0x00
+#define INT_RTC		0x01
+#define INT_UTXD1	0x02
+#define INT_UTXD0	0x03
+#define INT_SIO		0x04
+#define INT_IIC		0x05
+#define INT_URXD1	0x06
+#define INT_URXD0	0x07
+#define INT_TIMER5	0x08
+#define INT_TIMER4	0x09
+#define INT_TIMER3	0x0A
+#define INT_TIMER2	0x0B
+#define INT_TIMER1	0x0C
+#define INT_TIMER0	0x0D
+#define INT_UERR01	0x0E
+#define INT_WDT		0x1F
+#define INT_BDMA1	0x10
+#define INT_BDMA0	0x11
+#define INT_ZDMA1	0x12
+#define INT_ZDMA0	0x13
+#define INT_TICK	0x14
+#define INT_EINT4567	0x15
+#define INT_EINT3	0x16
+#define INT_EINT2	0x17
+#define INT_EINT1	0x18
+#define INT_EINT0	0x19
+
+#define INT_GLOBAL	26
+
+struct rt_hw_register
+{
+	unsigned long r0;
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long r10;
+	unsigned long fp;
+	unsigned long ip;
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long pc;
+	unsigned long cpsr;
+	unsigned long ORIG_r0;
+};
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 118 - 0
libcpu/arm/s3c44b0/serial.c

@@ -0,0 +1,118 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ * 2006-09-20     Bernard      clean code according code style
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "s3c44b0.h"
+
+void rt_serial_init(void);
+void rt_console_puts(const char* str);
+void rt_serial_putc(const char c);
+
+#define	USTAT_RCV_READY		0x01	/* receive data ready */
+#define	USTAT_TXB_EMPTY		0x02	/* tx buffer empty */
+
+rt_inline void serial_flush_input(void)
+{
+	volatile unsigned int tmp;
+
+	/* keep on reading as long as the receiver is not empty */
+	while(UTRSTAT0 & USTAT_RCV_READY) tmp = URXH0;
+}
+
+rt_inline void serial_flush_output(void)
+{
+	/* wait until the transmitter is no longer busy */
+	while(!(UTRSTAT0 & USTAT_TXB_EMPTY)) ;
+}
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * This function is used to display a string on console, normally, it's
+ * invoked by rt_kprintf
+ *
+ * @param str the displayed string
+ */
+void rt_console_puts(const char* str)
+{
+	while (*str)
+	{
+		rt_serial_putc (*str++);
+	}
+}
+
+/**
+ * This function initializes serial
+ */
+void rt_serial_init()
+{
+	rt_uint32_t divisor = 0;
+
+	divisor = 0x20;
+
+	serial_flush_output();
+	serial_flush_input();
+
+	/* UART interrupt off */
+	UCON0 	= 0;
+	/* FIFO disable */
+	UFCON0	=0x0;
+	UMCON0	=0x0;
+	/* set baudrate */
+ 	UBRDIV0 = divisor;
+
+	/* word length=8bit, stop bit = 1, no parity, use external clock */
+	ULCON0 	= 0x03|0x00|0x00;
+
+ 	UCON0 	= 0x5;
+}
+
+/**
+ * This function read a character from serial without interrupt enable mode
+ *
+ * @return the read char
+ */
+char rt_serial_getc()
+{
+	while ((UTRSTAT0 & USTAT_RCV_READY) == 0);
+
+	return URXH0;
+}
+
+/**
+ * This function will write a character to serial without interrupt enable mode
+ *
+ * @param c the char to write
+ */
+void rt_serial_putc(const char c)
+{
+	/*
+		to be polite with serial console add a line feed
+		to the carriage return character
+	*/
+	if (c=='\n')rt_serial_putc('\r');
+
+	/* wait for room in the transmit FIFO */
+	while(!(UTRSTAT0 & USTAT_TXB_EMPTY));
+
+	UTXH0 = (rt_uint8_t)c;
+}
+
+/*@}*/

+ 60 - 0
libcpu/arm/s3c44b0/stack.c

@@ -0,0 +1,60 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ */
+#include <rtthread.h>
+#include "s3c44b0.h"
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	*(stk) 	 = (unsigned long)tentry;		/* entry point */
+	*(--stk) = (unsigned long)texit;		/* lr */
+	*(--stk) = 0;							/* r12 */
+	*(--stk) = 0;							/* r11 */
+	*(--stk) = 0;							/* r10 */
+	*(--stk) = 0;							/* r9 */
+	*(--stk) = 0;							/* r8 */
+	*(--stk) = 0;							/* r7 */
+	*(--stk) = 0;							/* r6 */
+	*(--stk) = 0;							/* r5 */
+	*(--stk) = 0;							/* r4 */
+	*(--stk) = 0;							/* r3 */
+	*(--stk) = 0;							/* r2 */
+	*(--stk) = 0;							/* r1 */
+	*(--stk) = (unsigned long)parameter;	/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 257 - 0
libcpu/arm/s3c44b0/start_gcc.S

@@ -0,0 +1,257 @@
+/*
+ * File      : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ * 2006-09-20     Bernard      clean the code
+ */
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+.section .init, "ax"
+.code 32
+.globl _start
+_start:
+	b reset
+	ldr	pc, _vector_undef
+	ldr	pc, _vector_swi
+	ldr	pc, _vector_pabt
+	ldr	pc, _vector_dabt
+	ldr	pc, _vector_resv
+	ldr	pc, _vector_irq
+	ldr	pc, _vector_fiq
+
+_vector_undef:	.word vector_undef
+_vector_swi:	.word vector_swi
+_vector_pabt:	.word vector_pabt
+_vector_dabt:	.word vector_dabt
+_vector_resv:	.word vector_resv
+_vector_irq:	.word vector_irq
+_vector_fiq:	.word vector_fiq
+
+.text
+.code 32
+
+/*
+ * rtthread kernel start and end
+ * which are defined in linker script
+ */
+.globl _rtthread_start
+_rtthread_start:.word _start
+.globl _rtthread_end
+_rtthread_end:	.word  _end
+
+/*
+ * rtthread bss start and end
+ * which are defined in linker script
+ */
+.globl _bss_start
+_bss_start:	.word __bss_start
+.globl _bss_end
+_bss_end:	.word __bss_end
+
+#if defined(__FLASH_BUILD__)
+/*
+ * TEXT_BASE, 
+ * which is defined in macro of make
+ */
+_TEXT_BASE: .word	TEXT_BASE
+#endif
+
+	.equ WTCON,		0x1d30000
+	.equ INTCON,	0x1e00000
+	.equ INTMSK, 	0x1e0000c
+
+/* the system entry */
+reset:
+	/* enter svc mode */
+	msr cpsr_c, #SVCMODE|NOINT
+
+	/*watch dog disable */
+	ldr r0,=WTCON
+    ldr r1,=0x0 		
+    str r1,[r0]
+	
+	/* all interrupt disable */
+	ldr r0,=INTMSK
+	ldr r1,=0x07ffffff
+	str r1,[r0]
+	
+	ldr	r1, =INTCON
+	ldr	r0, =0x05
+	str	r0, [r1]
+
+#if defined(__FLASH_BUILD__)
+	/* init lowlevel */
+	bl lowlevel_init
+#endif
+
+	/* setup stack */
+	bl stack_setup
+	
+#if defined(__FLASH_BUILD__)
+	mov r0, #0x0			/* r0 <- flash base address         */
+	ldr r1, _TEXT_BASE		/* r1 <- the taget address          */
+	
+	ldr	r2, _rtthread_start
+	ldr	r3, _bss_start
+	sub	r2, r3, r2			/* r2 <- size of rtthread kernel    */
+	add	r2, r0, r2			/* r2 <- source end address         */
+	
+copy_loop:
+	ldmia	r0!, {r3-r10}	/* copy from source address [r0]    */
+	stmia	r1!, {r3-r10}	/* copy to   target address [r1]    */
+	cmp	r0, r2				/* until source end addreee [r2]    */
+	ble	copy_loop
+#endif
+	
+	/* start RT-Thread Kernel */
+	ldr	pc, _rtthread_startup
+
+_rtthread_startup: .word rtthread_startup
+
+	.equ USERMODE, 	0x10
+	.equ FIQMODE, 	0x11
+	.equ IRQMODE, 	0x12
+	.equ SVCMODE, 	0x13
+	.equ ABORTMODE, 0x17
+	.equ UNDEFMODE, 0x1b
+	.equ MODEMASK, 	0x1f
+	.equ NOINT,		0xc0
+
+/* exception handlers */
+vector_undef:	bl rt_hw_trap_udef
+vector_swi:		bl rt_hw_trap_swi
+vector_pabt: 	bl rt_hw_trap_pabt
+vector_dabt:	bl rt_hw_trap_dabt
+vector_resv: 	bl rt_hw_trap_resv
+
+.globl rt_interrupt_enter
+.globl rt_interrupt_leave
+.globl rt_thread_switch_interrput_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+vector_irq:	
+	stmfd	sp!, {r0-r12,lr}
+	bl  led_off
+	bl	rt_interrupt_enter
+	bl	rt_hw_trap_irq
+	bl	rt_interrupt_leave
+
+	/* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
+	ldr	r0, =rt_thread_switch_interrput_flag
+	ldr	r1, [r0]
+	cmp	r1, #1
+	beq	_interrupt_thread_switch
+
+	ldmfd	sp!, {r0-r12,lr}
+	subs	pc, lr, #4
+
+	.align	5
+vector_fiq:
+	stmfd sp!,{r0-r7,lr}
+	bl rt_hw_trap_fiq
+	ldmfd sp!,{r0-r7,lr}
+	subs pc,lr,#4
+
+_interrupt_thread_switch:
+	mov	r1, #0				@ clear rt_thread_switch_interrput_flag
+	str	r1, [r0]
+
+	ldmfd sp!, {r0-r12,lr}	@ reload saved registers
+	stmfd sp!, {r0-r3}		@ save r0-r3
+	mov	r1, sp
+	add	sp, sp, #16			@ restore sp
+	sub	r2, lr, #4			@ save old task's pc to r2
+
+	mrs	r3, spsr			@ disable interrupt
+	orr	r0, r3, #NOINT
+	msr	spsr_c, r0
+
+	ldr	r0,  =.+8			@ switch to interrupted task's stack
+	movs pc, r0
+
+	stmfd sp!, {r2}			@ push old task's pc
+	stmfd sp!, {r4-r12,lr}	@ push old task's lr,r12-r4
+	mov	r4, r1				@ Special optimised code below
+	mov	r5, r3
+	ldmfd r4!, {r0-r3}
+	stmfd sp!, {r0-r3}		@ push old task's r3-r0
+	stmfd sp!, {r5}			@ push old task's psr
+	mrs	r4, spsr
+	stmfd sp!, {r4}			@ push old task's spsr
+
+	ldr	r4, =rt_interrupt_from_thread
+	ldr	r5, [r4]
+	str	sp, [r5]			@ store sp in preempted tasks's TCB
+
+	ldr	r6, =rt_interrupt_to_thread
+	ldr	r6, [r6]
+	ldr	sp, [r6]			@ get new task's stack pointer
+
+	ldmfd sp!, {r4}			@ pop new task's spsr
+	msr	SPSR_cxsf, r4
+	ldmfd sp!, {r4}			@ pop new task's psr
+	msr CPSR_cxsf, r4
+
+	ldmfd sp!, {r0-r12,lr,pc}	@ pop new task's r0-r12,lr & pc
+
+/* each mode stack memory */
+UNDSTACK_START:	.word _undefined_stack_start + 128
+ABTSTACK_START:	.word _abort_stack_start + 128
+FIQSTACK_START:	.word _fiq_stack_start + 1024
+IRQSTACK_START:	.word _irq_stack_start + 1024
+SVCSTACK_START: .word _svc_stack_start + 4096
+
+stack_setup:
+	/* undefined instruction mode */
+	msr cpsr_c, #UNDEFMODE|NOINT
+	ldr sp, UNDSTACK_START
+
+	/* abort mode */
+	msr cpsr_c, #ABORTMODE|NOINT
+	ldr sp, ABTSTACK_START
+
+	/* FIQ mode */
+	msr cpsr_c, #FIQMODE|NOINT
+	ldr sp, FIQSTACK_START
+
+	/* IRQ mode */
+	msr cpsr_c, #IRQMODE|NOINT
+	ldr sp, IRQSTACK_START
+
+	/* supervisor mode */
+	msr cpsr_c, #SVCMODE|NOINT
+	ldr sp, SVCSTACK_START
+
+	mov	pc,lr				@ The LR register may be not valid for the mode changes.
+
+.globl led_on
+led_on:
+	ldr	r1,	=0x1d20014		@ r1<-PDATC
+	ldr	r0,	[r1]			@ r0<-[r1]
+	orr	r0,	r0, #0x0e		@ r0=r0 or 0x0e
+	str	r0,	[r1]			@ r0->[r1]
+	mov	pc, lr
+
+.globl led_off
+led_off:
+	ldr	r1,	=0x1d20010		@ r1<-PCONC
+	ldr	r0,	=0x5f555555		@ r0<-0x5f555555
+	str	r0,	[r1]			@ r0->[r1]
+
+	ldr	r1,	=0x1d20014		@ r1<-PDATC
+	ldr	r0,	=0x0			@ r0<-00
+	str	r0,	[r1]			@ r0->[r1]
+
+	mov	pc, lr

+ 1072 - 0
libcpu/arm/s3c44b0/start_rvds.s

@@ -0,0 +1,1072 @@
+;/*****************************************************************************/
+;/* S3C44B0X.S: Startup file for Samsung S3C44B0X                             */
+;/*****************************************************************************/
+;/* <<< Use Configuration Wizard in Context Menu >>>                          */ 
+;/*****************************************************************************/
+;/* This file is part of the uVision/ARM development tools.                   */
+;/* Copyright (c) 2005-2006 Keil Software. All rights reserved.               */
+;/* This software may only be used under the terms of a valid, current,       */
+;/* end user licence from KEIL for a compatible version of KEIL software      */
+;/* development tools. Nothing else gives you the right to use this software. */
+;/*****************************************************************************/
+
+
+; *** Startup Code (executed after Reset) ***
+
+
+; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
+
+Mode_USR        EQU     0x10
+Mode_FIQ        EQU     0x11
+Mode_IRQ        EQU     0x12
+Mode_SVC        EQU     0x13
+Mode_ABT        EQU     0x17
+Mode_UND        EQU     0x1B
+Mode_SYS        EQU     0x1F
+
+I_Bit           EQU     0x80            ; when I bit is set, IRQ is disabled
+F_Bit           EQU     0x40            ; when F bit is set, FIQ is disabled
+
+
+;// <h> Stack Configuration (Stack Sizes in Bytes)
+;//   <o0> Undefined Mode      <0x0-0xFFFFFFFF:8>
+;//   <o1> Supervisor Mode     <0x0-0xFFFFFFFF:8>
+;//   <o2> Abort Mode          <0x0-0xFFFFFFFF:8>
+;//   <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
+;//   <o4> Interrupt Mode      <0x0-0xFFFFFFFF:8>
+;//   <o5> User/System Mode    <0x0-0xFFFFFFFF:8>
+;// </h>
+
+UND_Stack_Size  EQU     0x00000000
+SVC_Stack_Size  EQU     0x00000100
+ABT_Stack_Size  EQU     0x00000000
+FIQ_Stack_Size  EQU     0x00000000
+IRQ_Stack_Size  EQU     0x00000100
+USR_Stack_Size  EQU     0x00000100
+
+ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                         FIQ_Stack_Size + IRQ_Stack_Size)
+
+                AREA    STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem       SPACE   USR_Stack_Size
+__initial_sp    SPACE   ISR_Stack_Size
+Stack_Top
+
+
+;// <h> Heap Configuration
+;//   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF>
+;// </h>
+
+Heap_Size       EQU     0x00000000
+
+                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem        SPACE   Heap_Size
+__heap_limit
+
+
+; CPU Wrapper and Bus Priorities definitions
+CPUW_BASE       EQU     0x01C00000      ; CPU Wrapper Base Address
+SYSCFG_OFS      EQU     0x00            ; SYSCFG Offset
+NCACHBE0_OFS    EQU     0x04            ; NCACHBE0 Offset
+NCACHBE1_OFS    EQU     0x08            ; NCACHBE0 Offset
+BUSP_BASE       EQU     0x01C40000      ; Bus Priority Base Address
+SBUSCON_OFS     EQU     0x00            ; SBUSCON Offset
+
+;// <e> CPU Wrapper and Bus Priorities
+;//   <h> CPU Wrapper
+;//     <o1.0>      SE: Stall Enable
+;//     <o1.1..2>   CM: Cache Mode
+;//                 <0=> Disable Cache (8kB SRAM)
+;//                 <1=> Half Cache Enable (4kB Cache, 4kB SRAM)
+;//                 <2=> Reserved
+;//                 <3=> Full Cache Enable (8kB Cache)
+;//     <o1.3>      WE: Write Buffer Enable
+;//     <o1.4>      RSE: Read Stall Enable
+;//     <o1.5>      DA: Data Abort  <0=> Enable <1=> Disable
+;//     <h> Non-cacheable Area 0
+;//       <o2.0..15>  Start Address     <0x0-0x0FFFF000:0x1000><#/0x1000>
+;//                   <i> SA = (Start Address) / 4k
+;//       <o2.16..31> End Address + 1   <0x0-0x10000000:0x1000><#/0x1000>
+;//                   <i> SE = (End Address + 1) / 4k
+;//     </h>
+;//     <h> Non-cacheable Area 1
+;//       <o3.0..15>  Start Address     <0x0-0x0FFFF000:0x1000><#/0x1000>
+;//                   <i> SA = (Start Address) / 4k
+;//       <o3.16..31> End Address + 1   <0x0-0x10000000:0x1000><#/0x1000>
+;//                   <i> SE = (End Address + 1) / 4k
+;//     </h>
+;//   </h>
+;//   <h> Bus Priorities
+;//     <o4.31>       FIX: Fixed Priorities
+;//     <o4.6..7>     LCD_DMA    <0=> 1st  <1=> 2nd  <2=> 3rd  <3=> 4th
+;//     <o4.4..5>     ZDMA       <0=> 1st  <1=> 2nd  <2=> 3rd  <3=> 4th
+;//     <o4.2..3>     BDMA       <0=> 1st  <1=> 2nd  <2=> 3rd  <3=> 4th
+;//     <o4.0..1>     nBREQ      <0=> 1st  <1=> 2nd  <2=> 3rd  <3=> 4th
+;//   </h>
+;// </e>
+SYS_SETUP       EQU     0
+SYSCFG_Val      EQU     0x00000001
+NCACHBE0_Val    EQU     0x00000000
+NCACHBE1_Val    EQU     0x00000000
+SBUSCON_Val     EQU     0x80001B1B
+
+
+;// <e> Vectored Interrupt Mode (for IRQ)
+;//   <o1.25> EINT0      <i> External Interrupt 0
+;//   <o1.24> EINT1      <i> External Interrupt 1
+;//   <o1.23> EINT2      <i> External Interrupt 2                        
+;//   <o1.22> EINT3      <i> External Interrupt 3
+;//   <o1.21> EINT4567   <i> External Interrupt 4/5/6/7
+;//   <o1.20> TICK       <i> RTC Time Tick Interrupt
+;//   <o1.19> ZDMA0      <i> General DMA0 Interrupt
+;//   <o1.18> ZDMA1      <i> General DMA1 Interrupt
+;//   <o1.17> BDMA0      <i> Bridge DMA0 Interrupt
+;//   <o1.16> BDMA1      <i> Bridge DMA1 Interrupt
+;//   <o1.15> WDT        <i> Watchdog Timer Interrupt
+;//   <o1.14> UERR01     <i> UART0/1 Error Interrupt
+;//   <o1.13> TIMER0     <i> Timer0 Interrupt
+;//   <o1.12> TIMER1     <i> Timer1 Interrupt
+;//   <o1.11> TIMER2     <i> Timer2 Interrupt
+;//   <o1.10> TIMER3     <i> Timer3 Interrupt
+;//   <o1.9>  TIMER4     <i> Timer4 Interrupt
+;//   <o1.8>  TIMER5     <i> Timer5 Interrupt
+;//   <o1.7>  URXD0      <i> UART0 Rx Interrupt
+;//   <o1.6>  URXD1      <i> UART1 Rx Interrupt
+;//   <o1.5>  IIC        <i> IIC Interrupt
+;//   <o1.4>  SIO        <i> SIO Interrupt
+;//   <o1.3>  UTXD0      <i> UART0 Tx Interrupt
+;//   <o1.2>  UTXD1      <i> UART1 Tx Interrupt
+;//   <o1.1>  RTC        <i> RTC Alarm Interrupt
+;//   <o1.0>  ADC        <i> ADC EOC Interrupt
+;// </e>
+VIM_SETUP       EQU     0
+VIM_CFG         EQU     0x00000000
+
+
+; Clock Management definitions
+CLK_BASE        EQU     0x01D80000      ; Clock Base Address
+PLLCON_OFS      EQU     0x00            ; PLLCON Offset
+CLKCON_OFS      EQU     0x04            ; CLKCON Offset
+CLKSLOW_OFS     EQU     0x08            ; CLKSLOW Offset
+LOCKTIME_OFS    EQU     0x0C            ; LOCKTIME Offset
+
+;// <e> Clock Management
+;//   <h> PLL Settings
+;//   <i> Fpllo = (m * Fin) / (p * 2^s), 20MHz < Fpllo < 66MHz
+;//     <o1.12..19> MDIV: Main divider <0x0-0xFF>
+;//                 <i> m = MDIV + 8
+;//     <o1.4..9>   PDIV: Pre-divider  <0x0-0x3F>
+;//                 <i> p = PDIV + 2, 1MHz <= Fin/p < 2MHz
+;//     <o1.0..1>   SDIV: Post Divider <0x0-0x03>
+;//                 <i> s = SDIV, Fpllo * 2^s < 170MHz
+;//     <o4.0..11>  LTIME CNT: PLL Lock Time Count  <0x0-0x0FFF>
+;//   </h>
+;//   <h> Master Clock
+;//   <i> PLL Clock:  Fout = Fpllo
+;//   <i> Slow Clock: Fout = Fin / (2 * SLOW_VAL), SLOW_VAL > 0
+;//   <i> Slow Clock: Fout = Fin, SLOW_VAL = 0
+;//     <o3.5>      PLL_OFF: PLL Off
+;//                 <i> PLL is turned Off only when SLOW_BIT = 1
+;//     <o3.4>      SLOW_BIT: Slow Clock
+;//     <o3.0..3>   SLOW_VAL: Slow Clock divider    <0x0-0x0F>
+;//   </h>
+;//   <h> Clock Generation
+;//     <o2.14>     IIS       <0=> Disable  <1=> Enable
+;//     <o2.13>     IIC       <0=> Disable  <1=> Enable
+;//     <o2.12>     ADC       <0=> Disable  <1=> Enable
+;//     <o2.11>     RTC       <0=> Disable  <1=> Enable
+;//     <o2.10>     GPIO      <0=> Disable  <1=> Enable
+;//     <o2.9>      UART1     <0=> Disable  <1=> Enable
+;//     <o2.8>      UART0     <0=> Disable  <1=> Enable
+;//     <o2.7>      BDMA0,1   <0=> Disable  <1=> Enable
+;//     <o2.6>      LCDC      <0=> Disable  <1=> Enable
+;//     <o2.5>      SIO       <0=> Disable  <1=> Enable
+;//     <o2.4>      ZDMA0,1   <0=> Disable  <1=> Enable
+;//     <o2.3>      PWMTIMER  <0=> Disable  <1=> Enable
+;//   </h>
+;// </e>
+CLK_SETUP       EQU     1
+PLLCON_Val      EQU     0x00038080
+CLKCON_Val      EQU     0x00007FF8
+CLKSLOW_Val     EQU     0x00000009
+LOCKTIME_Val    EQU     0x00000FFF
+
+
+; Watchdog Timer definitions
+WT_BASE         EQU     0x01D30000      ; WT Base Address
+WTCON_OFS       EQU     0x00            ; WTCON Offset
+WTDAT_OFS       EQU     0x04            ; WTDAT Offset
+WTCNT_OFS       EQU     0x08            ; WTCNT Offset
+
+;// <e> Watchdog Timer
+;//   <o1.5>      Watchdog Timer Enable/Disable
+;//   <o1.0>      Reset Enable/Disable
+;//   <o1.2>      Interrupt Enable/Disable
+;//   <o1.3..4>   Clock Select  
+;//               <0=> 1/16  <1=> 1/32  <2=> 1/64  <3=> 1/128
+;//               <i> Clock Division Factor
+;//   <o1.8..15>  Prescaler Value <0x0-0xFF>
+;//   <o2.0..15>  Time-out Value  <0x0-0xFFFF>
+;// </e>
+WT_SETUP        EQU     1
+WTCON_Val       EQU     0x00008000
+WTDAT_Val       EQU     0x00008000
+
+
+; Memory Controller definitions
+MC_BASE         EQU     0x01C80000      ; Memory Controller Base Address
+
+;// <e> Memory Controller
+MC_SETUP        EQU     1
+
+;//   <h> Bank 0
+;//     <o0.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o0.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o0.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o0.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o0.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o0.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o0.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 1
+;//     <o8.4..5>   DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.6>      WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.7>      ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o1.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o1.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o1.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o1.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o1.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o1.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o1.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 2
+;//     <o8.8..9>   DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.10>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.11>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o2.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o2.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o2.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o2.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o2.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o2.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o2.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 3
+;//     <o8.12..13> DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.14>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.15>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o3.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o3.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o3.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o3.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o3.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o3.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o3.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 4
+;//     <o8.16..17> DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.18>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.19>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o4.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o4.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o4.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o4.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o4.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o4.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o4.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 5
+;//     <o8.20..21> DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.22>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.23>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o5.0..1>   PMC: Page Mode Configuration
+;//                 <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//     <o5.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//     <o5.4..5>   Tcah: Address Holding Time after nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o5.6..7>   Toch: Chip Select Hold on nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o5.8..10>  Tacc: Access Cycle
+;//                 <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                 <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//     <o5.11..12> Tcos: Chip Select Set-up nOE
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     <o5.13..14> Tacs: Address Set-up before nGCSn
+;//                 <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//   </h>
+;//
+;//   <h> Bank 6
+;//     <o10.0..2>  BK76MAP: Bank 6/7 Memory Map
+;//                 <0=> 32M  <4=> 2M   <5=> 4M   <6=> 8M   <7=> 16M
+;//     <o8.24..25> DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.26>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.27>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o6.15..16> MT: Memory Type
+;//                 <0=> ROM or SRAM
+;//                 <1=> FP DRAMP
+;//                 <2=> EDO DRAM
+;//                 <3=> SDRAM
+;//     <h> ROM or SRAM
+;//       <o6.0..1>   PMC: Page Mode Configuration
+;//                   <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//       <o6.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//       <o6.4..5>   Tcah: Address Holding Time after nGCSn
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o6.6..7>   Toch: Chip Select Hold on nOE
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o6.8..10>  Tacc: Access Cycle
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                   <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//       <o6.11..12> Tcos: Chip Select Set-up nOE
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o6.13..14> Tacs: Address Set-up before nGCSn
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     </h>
+;//     <h> FP DRAM or EDO DRAM
+;//       <o6.0..1>   CAN: Columnn Address Number
+;//                   <0=> 8-bit   <1=> 9-bit   <2=> 10-bit  <3=> 11-bit
+;//       <o6.2>      Tcp: CAS Pre-charge
+;//                   <0=> 1 clk   <1=> 2 clks
+;//       <o6.3>      Tcas: CAS Pulse Width
+;//                   <0=> 1 clk   <1=> 2 clks
+;//       <o6.4..5>   Trcd: RAS to CAS Delay
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//     </h>
+;//     <h> SDRAM
+;//       <o6.0..1>   SCAN: Columnn Address Number
+;//                   <0=> 8-bit   <1=> 9-bit   <2=> 10-bit  <3=> Rsrvd
+;//       <o6.2..3>   Trcd: RAS to CAS Delay
+;//                   <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> Rsrvd
+;//       <o10.4>     SCLKEN: SCLK Selection (Bank 6/7)
+;//                   <0=> Normal
+;//                   <1=> Reduced Power 
+;//       <o11.0..2>  BL: Burst Length
+;//                   <0=> 1
+;//       <o11.3>     BT: Burst Type
+;//                   <0=> Sequential
+;//       <o11.4..6>  CL: CAS Latency
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks
+;//       <o11.7..8>  TM: Test Mode
+;//                   <0=> Mode Register Set
+;//       <o11.9>     WBL: Write Burst Length
+;//                   <0=> 0
+;//     </h>
+;//   </h>
+;//
+;//   <h> Bank 7
+;//     <o10.0..2>  BK76MAP: Bank 6/7 Memory Map
+;//                 <0=> 32M  <4=> 2M   <5=> 4M   <6=> 8M   <7=> 16M
+;//     <o8.28..29> DW: Data Bus Width
+;//                 <0=> 8-bit   <1=> 16-bit  <2=> 32-bit  <3=> Rsrvd
+;//     <o8.30>     WS: WAIT Status
+;//                 <0=> WAIT Disable
+;//                 <1=> WAIT Enable
+;//     <o8.31>     ST: SRAM Type
+;//                 <0=> Not using UB/LB
+;//                 <1=> Using UB/LB
+;//     <o7.15..16> MT: Memory Type
+;//                 <0=> ROM or SRAM
+;//                 <1=> FP DRAMP
+;//                 <2=> EDO DRAM
+;//                 <3=> SDRAM
+;//     <h> ROM or SRAM
+;//       <o7.0..1>   PMC: Page Mode Configuration
+;//                   <0=> 1 Data  <1=> 4 Data  <2=> 8 Data  <3=> 16 Data
+;//       <o7.2..3>   Tpac: Page Mode Access Cycle
+;//                 <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> 6 clks
+;//       <o7.4..5>   Tcah: Address Holding Time after nGCSn
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o7.6..7>   Toch: Chip Select Hold on nOE
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o7.8..10>  Tacc: Access Cycle
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//                   <4=> 6 clk   <5=> 8 clks  <6=> 10 clks <7=> 14 clks
+;//       <o7.11..12> Tcos: Chip Select Set-up nOE
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//       <o7.13..14> Tacs: Address Set-up before nGCSn
+;//                   <0=> 0 clk   <1=> 1 clk   <2=> 2 clks  <3=> 4 clks
+;//     </h>
+;//     <h> FP DRAM or EDO DRAM
+;//       <o7.0..1>   CAN: Columnn Address Number
+;//                   <0=> 8-bit   <1=> 9-bit   <2=> 10-bit  <3=> 11-bit
+;//       <o7.2>      Tcp: CAS Pre-charge
+;//                   <0=> 1 clk   <1=> 2 clks
+;//       <o7.3>      Tcas: CAS Pulse Width
+;//                   <0=> 1 clk   <1=> 2 clks
+;//       <o7.4..5>   Trcd: RAS to CAS Delay
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//     </h>
+;//     <h> SDRAM
+;//       <o7.0..1>   SCAN: Columnn Address Number
+;//                   <0=> 8-bit   <1=> 9-bit   <2=> 10-bit  <3=> Rsrvd
+;//       <o7.2..3>   Trcd: RAS to CAS Delay
+;//                   <0=> 2 clks  <1=> 3 clks  <2=> 4 clks  <3=> Rsrvd
+;//       <o10.4>     SCLKEN: SCLK Selection (Bank 6/7)
+;//                   <0=> Normal
+;//                   <1=> Reduced Power 
+;//       <o12.0..2>  BL: Burst Length
+;//                   <0=> 1
+;//       <o12.3>     BT: Burst Type
+;//                   <0=> Sequential
+;//       <o12.4..6>  CL: CAS Latency
+;//                   <0=> 1 clk   <1=> 2 clks  <2=> 3 clks
+;//       <o12.7..8>  TM: Test Mode
+;//                   <0=> Mode Register Set
+;//       <o12.9>     WBL: Write Burst Length
+;//                   <0=> 0
+;//     </h>
+;//   </h>
+;//
+;//   <h> Refresh
+;//     <o9.23>     REFEN: DRAM/SDRAM Refresh
+;//                 <0=> Disable <1=> Enable
+;//     <o9.22>     TREFMD: DRAM/SDRAM Refresh Mode
+;//                 <0=> CBR/Auto Refresh
+;//                 <1=> Self Refresh
+;//     <o9.20..21> Trp: DRAM/SDRAM RAS Pre-charge Time
+;//                 <0=> 1.5 clks (DRAM) / 2 clks (SDRAM)
+;//                 <1=> 2.5 clks (DRAM) / 3 clks (SDRAM)
+;//                 <2=> 3.5 clks (DRAM) / 4 clks (SDRAM)
+;//                 <3=> 4.5 clks (DRAM) / Rsrvd (SDRAM)
+;//     <o9.18..19> Trc: SDRAM RC Min Time
+;//                 <0=> 4 clks  <1=> 5 clks  <2=> 6 clks  <3=> 7 clks
+;//     <o9.16..17> Tchr: DRAM CAS Hold Time
+;//                 <0=> 1 clks  <1=> 2 clks  <2=> 3 clks  <3=> 4 clks
+;//     <o9.0..10>  Refresh Counter <0x0-0x07FF>
+;//                 <i> Refresh Period = (2^11 - Refresh Count + 1) / MCLK
+;//   </h>
+BANKCON0_Val    EQU     0x00000700
+BANKCON1_Val    EQU     0x00000700
+BANKCON2_Val    EQU     0x00000700
+BANKCON3_Val    EQU     0x00000700
+BANKCON4_Val    EQU     0x00000700
+BANKCON5_Val    EQU     0x00000700
+BANKCON6_Val    EQU     0x00018008
+BANKCON7_Val    EQU     0x00018008
+BWSCON_Val      EQU     0x00000000
+REFRESH_Val     EQU     0x00AC0000
+BANKSIZE_Val    EQU     0x00000000
+MRSRB6_Val      EQU     0x00000000
+MRSRB7_Val      EQU     0x00000000
+
+;// </e> End of MC
+
+
+; I/O Ports definitions
+PIO_BASE        EQU     0x01D20000      ; PIO Base Address
+PCONA_OFS       EQU     0x00            ; PCONA Offset
+PCONB_OFS       EQU     0x08            ; PCONB Offset
+PCONC_OFS       EQU     0x10            ; PCONC Offset
+PCOND_OFS       EQU     0x1C            ; PCOND Offset
+PCONE_OFS       EQU     0x28            ; PCONE Offset
+PCONF_OFS       EQU     0x34            ; PCONF Offset
+PCONG_OFS       EQU     0x40            ; PCONG Offset
+PUPC_OFS        EQU     0x18            ; PUPC Offset
+PUPD_OFS        EQU     0x24            ; PUPD Offset
+PUPE_OFS        EQU     0x30            ; PUPE Offset
+PUPF_OFS        EQU     0x3C            ; PUPF Offset
+PUPG_OFS        EQU     0x48            ; PUPG Offset
+SPUCR_OFS       EQU     0x4C            ; SPUCR Offset
+
+;// <e> I/O Configuration
+PIO_SETUP       EQU     0
+
+;//   <e> Port A
+;//     <o1.0>      PA0  <0=> Output   <1=> ADDR0
+;//     <o1.1>      PA1  <0=> Output   <1=> ADDR16
+;//     <o1.2>      PA2  <0=> Output   <1=> ADDR17
+;//     <o1.3>      PA3  <0=> Output   <1=> ADDR18
+;//     <o1.4>      PA4  <0=> Output   <1=> ADDR19
+;//     <o1.5>      PA5  <0=> Output   <1=> ADDR20
+;//     <o1.6>      PA6  <0=> Output   <1=> ADDR21
+;//     <o1.7>      PA7  <0=> Output   <1=> ADDR22
+;//     <o1.8>      PA8  <0=> Output   <1=> ADDR23
+;//     <o1.9>      PA9  <0=> Output   <1=> ADDR24
+;//   </e>
+PIOA_SETUP      EQU     1
+PCONA_Val       EQU     0x000003FF
+
+;//   <e> Port B
+;//     <o1.0>      PB0  <0=> Output   <1=> SCKE
+;//     <o1.1>      PB1  <0=> Output   <1=> CKLK
+;//     <o1.2>      PB2  <0=> Output   <1=> nSCAS/nCAS2
+;//     <o1.3>      PB3  <0=> Output   <1=> nSRAS/nCAS3
+;//     <o1.4>      PB4  <0=> Output   <1=> nWBE2/nBE2/DQM2
+;//     <o1.5>      PB5  <0=> Output   <1=> nWBE3/nBE3/DQM3
+;//     <o1.6>      PB6  <0=> Output   <1=> nGCS1
+;//     <o1.7>      PB7  <0=> Output   <1=> nGCS2
+;//     <o1.8>      PB8  <0=> Output   <1=> nGCS3
+;//     <o1.9>      PB9  <0=> Output   <1=> nGCS4
+;//     <o1.10>     PB10 <0=> Output   <1=> nGCS5
+;//   </e>
+PIOB_SETUP      EQU     1
+PCONB_Val       EQU     0x000007FF
+
+;//   <e> Port C
+;//     <o1.0..1>   PC0  <0=> Input    <1=> Output   <2=> DATA16   <3=> IISLRCK
+;//     <o1.2..3>   PC1  <0=> Input    <1=> Output   <2=> DATA17   <3=> IISDO
+;//     <o1.4..5>   PC2  <0=> Input    <1=> Output   <2=> DATA18   <3=> IISDI
+;//     <o1.6..7>   PC3  <0=> Input    <1=> Output   <2=> DATA19   <3=> IISCLK
+;//     <o1.8..9>   PC4  <0=> Input    <1=> Output   <2=> DATA20   <3=> VD7
+;//     <o1.10..11> PC5  <0=> Input    <1=> Output   <2=> DATA21   <3=> VD6
+;//     <o1.12..13> PC6  <0=> Input    <1=> Output   <2=> DATA22   <3=> VD5
+;//     <o1.14..15> PC7  <0=> Input    <1=> Output   <2=> DATA23   <3=> VD4
+;//     <o1.16..17> PC8  <0=> Input    <1=> Output   <2=> DATA24   <3=> nXDACK1
+;//     <o1.18..19> PC9  <0=> Input    <1=> Output   <2=> DATA25   <3=> nXDREQ1
+;//     <o1.20..21> PC10 <0=> Input    <1=> Output   <2=> DATA26   <3=> nRTS1
+;//     <o1.22..23> PC11 <0=> Input    <1=> Output   <2=> DATA27   <3=> nCTS1
+;//     <o1.24..25> PC12 <0=> Input    <1=> Output   <2=> DATA28   <3=> TxD1
+;//     <o1.26..27> PC13 <0=> Input    <1=> Output   <2=> DATA29   <3=> RxD1
+;//     <o1.28..29> PC14 <0=> Input    <1=> Output   <2=> DATA30   <3=> nRTS0
+;//     <o1.30..31> PC15 <0=> Input    <1=> Output   <2=> DATA31   <3=> nCTS0
+;//     <h> Pull-up Resistors
+;//       <o2.0>    PC0 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.1>    PC1 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.2>    PC2 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.3>    PC3 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.4>    PC4 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.5>    PC5 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.6>    PC6 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.7>    PC7 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.8>    PC8 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.9>    PC9 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.10>   PC10 Pull-up       <0=> Enabled  <1=> Disabled
+;//       <o2.11>   PC11 Pull-up       <0=> Enabled  <1=> Disabled
+;//       <o2.12>   PC12 Pull-up       <0=> Enabled  <1=> Disabled
+;//       <o2.13>   PC13 Pull-up       <0=> Enabled  <1=> Disabled
+;//       <o2.14>   PC14 Pull-up       <0=> Enabled  <1=> Disabled
+;//       <o2.15>   PC15 Pull-up       <0=> Enabled  <1=> Disabled
+;//     </h>
+;//   </e>
+PIOC_SETUP      EQU     1
+PCONC_Val       EQU     0xAAAAAAAA
+PUPC_Val        EQU     0x00000000
+
+;//   <e> Port D
+;//     <o1.0..1>   PD0  <0=> Input    <1=> Output   <2=> VD0      <3=> Reserved
+;//     <o1.2..3>   PD1  <0=> Input    <1=> Output   <2=> VD1      <3=> Reserved
+;//     <o1.4..5>   PD2  <0=> Input    <1=> Output   <2=> VD2      <3=> Reserved
+;//     <o1.6..7>   PD3  <0=> Input    <1=> Output   <2=> VD3      <3=> Reserved
+;//     <o1.8..9>   PD4  <0=> Input    <1=> Output   <2=> VCLK     <3=> Reserved
+;//     <o1.10..11> PD5  <0=> Input    <1=> Output   <2=> VLINE    <3=> Reserved
+;//     <o1.12..13> PD6  <0=> Input    <1=> Output   <2=> VM       <3=> Reserved
+;//     <o1.14..15> PD7  <0=> Input    <1=> Output   <2=> VFRAME   <3=> Reserved
+;//     <h> Pull-up Resistors
+;//       <o2.0>    PD0 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.1>    PD1 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.2>    PD2 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.3>    PD3 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.4>    PD4 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.5>    PD5 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.6>    PD6 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.7>    PD7 Pull-up        <0=> Enabled  <1=> Disabled
+;//     </h>
+;//   </e>
+PIOD_SETUP      EQU     1
+PCOND_Val       EQU     0x00000000
+PUPD_Val        EQU     0x00000000
+
+;//   <e> Port E
+;//     <o1.0..1>   PE0  <0=> Input    <1=> Output   <2=> Fpllo    <3=> Fout
+;//     <o1.2..3>   PE1  <0=> Input    <1=> Output   <2=> TxD0     <3=> Reserved
+;//     <o1.4..5>   PE2  <0=> Input    <1=> Output   <2=> RxD0     <3=> Reserved
+;//     <o1.6..7>   PE3  <0=> Input    <1=> Output   <2=> TOUT0    <3=> Reserved
+;//     <o1.8..9>   PE4  <0=> Input    <1=> Output   <2=> TOUT1    <3=> TCLK
+;//     <o1.10..11> PE5  <0=> Input    <1=> Output   <2=> TOUT2    <3=> TCLK
+;//     <o1.12..13> PE6  <0=> Input    <1=> Output   <2=> TOUT3    <3=> VD6
+;//     <o1.14..15> PE7  <0=> Input    <1=> Output   <2=> TOUT4    <3=> VD7
+;//     <o1.16..17> PE8  <0=> Input    <1=> Output   <2=> CODECLK  <3=> Reserved
+;//     <h> Pull-up Resistors
+;//       <o2.0>    PE0 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.1>    PE1 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.2>    PE2 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.3>    PE3 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.4>    PE4 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.5>    PE5 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.6>    PE6 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.7>    PE7 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.8>    PE8 Pull-up        <0=> Enabled  <1=> Disabled
+;//     </h>
+;//   </e>
+PIOE_SETUP      EQU     1
+PCONE_Val       EQU     0x00000000
+PUPE_Val        EQU     0x00000000
+
+;//   <e> Port F
+;//     <o1.0..1>   PF0  <0=> Input    <1=> Output   <2=> IICSCL   <3=> Reserved
+;//     <o1.2..3>   PF1  <0=> Input    <1=> Output   <2=> IICSDA   <3=> Reserved
+;//     <o1.4..5>   PF2  <0=> Input    <1=> Output   <2=> nWAIT    <3=> Reserved
+;//     <o1.6..7>   PF3  <0=> Input    <1=> Output   <2=> nXBACK   <3=> nXDACK0
+;//     <o1.8..9>   PF4  <0=> Input    <1=> Output   <2=> nXBREQ   <3=> nXDREQ0
+;//     <o1.10..12> PF5  <0=> Input    <1=> Output   <2=> nRTS1    <3=> SIOTxD
+;//                      <4=> IISLRCK  <5=> Reserved <6=> Reserved <7=> Reserved
+;//     <o1.13..15> PF6  <0=> Input    <1=> Output   <2=> TxD1     <3=> SIORDY
+;//                      <4=> IISDO    <5=> Reserved <6=> Reserved <7=> Reserved
+;//     <o1.16..18> PF7  <0=> Input    <1=> Output   <2=> RxD1     <3=> SIORxD
+;//                      <4=> IISDI    <5=> Reserved <6=> Reserved <7=> Reserved
+;//     <o1.19..21> PF8  <0=> Input    <1=> Output   <2=> nCTS1    <3=> SIOCLK
+;//                      <4=> IISCLK   <5=> Reserved <6=> Reserved <7=> Reserved
+;//     <h> Pull-up Resistors
+;//       <o2.0>    PF0 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.1>    PF1 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.2>    PF2 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.3>    PF3 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.4>    PF4 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.5>    PF5 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.6>    PF6 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.7>    PF7 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.8>    PF8 Pull-up        <0=> Enabled  <1=> Disabled
+;//     </h>
+;//   </e>
+PIOF_SETUP      EQU     1
+PCONF_Val       EQU     0x00000000
+PUPF_Val        EQU     0x00000000
+
+;//   <e> Port G
+;//     <o1.0..1>   PG0  <0=> Input    <1=> Output   <2=> VD4      <3=> EINT0
+;//     <o1.2..3>   PG1  <0=> Input    <1=> Output   <2=> VD5      <3=> EINT1
+;//     <o1.4..5>   PG2  <0=> Input    <1=> Output   <2=> nCTS0    <3=> EINT2
+;//     <o1.6..7>   PG3  <0=> Input    <1=> Output   <2=> nRTS0    <3=> EINT3
+;//     <o1.8..9>   PG4  <0=> Input    <1=> Output   <2=> IISCLK   <3=> EINT4
+;//     <o1.10..11> PG5  <0=> Input    <1=> Output   <2=> IISDI    <3=> EINT5
+;//     <o1.12..13> PG6  <0=> Input    <1=> Output   <2=> IISDO    <3=> EINT6
+;//     <o1.14..15> PG7  <0=> Input    <1=> Output   <2=> IISLRCK  <3=> EINT7
+;//     <h> Pull-up Resistors
+;//       <o2.0>    PG0 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.1>    PG1 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.2>    PG2 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.3>    PG3 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.4>    PG4 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.5>    PG5 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.6>    PG6 Pull-up        <0=> Enabled  <1=> Disabled
+;//       <o2.7>    PG7 Pull-up        <0=> Enabled  <1=> Disabled
+;//     </h>
+;//   </e>
+PIOG_SETUP      EQU     1
+PCONG_Val       EQU     0x00000000
+PUPG_Val        EQU     0x00000000
+
+;//   <e> Special Pull-up
+;//     <o1.0>    SPUCR0: DATA[7:0] Pull-up Resistor    
+;//               <0=> Enabled  <1=> Disabled
+;//     <o1.1>    SPUCR1: DATA[15:8] Pull-up Resistor    
+;//               <0=> Enabled  <1=> Disabled
+;//     <o1.2>    HZ@STOP
+;//               <0=> Prevoius state of PAD
+;//               <1=> HZ @ Stop
+;//   </e>
+PSPU_SETUP      EQU     1
+SPUCR_Val       EQU     0x00000004
+
+;// </e>
+  
+
+                PRESERVE8
+                
+
+; Area Definition and Entry Point
+;  Startup Code must be linked first at Address at which it expects to run.
+
+                AREA    RESET, CODE, READONLY
+                ARM
+
+
+; Exception Vectors
+;  Mapped to Address 0.
+;  Absolute addressing mode must be used.
+;  Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors         LDR     PC, Reset_Addr         
+                LDR     PC, Undef_Addr
+                LDR     PC, SWI_Addr
+                LDR     PC, PAbt_Addr
+                LDR     PC, DAbt_Addr
+                NOP                            ; Reserved Vector 
+                LDR     PC, IRQ_Addr
+                LDR     PC, FIQ_Addr
+
+Reset_Addr      DCD     Reset_Handler
+Undef_Addr      DCD     Undef_Handler
+SWI_Addr        DCD     SWI_Handler
+PAbt_Addr       DCD     PAbt_Handler
+DAbt_Addr       DCD     DAbt_Handler
+                DCD     0                      ; Reserved Address 
+IRQ_Addr        DCD     IRQ_Handler
+FIQ_Addr        DCD     FIQ_Handler
+
+Undef_Handler   B       Undef_Handler
+SWI_Handler     B       SWI_Handler
+PAbt_Handler    B       PAbt_Handler
+DAbt_Handler    B       DAbt_Handler
+FIQ_Handler     B       FIQ_Handler
+
+
+; CPU Wrapper and Bus Priorities Configuration
+                IF      SYS_SETUP <> 0
+SYS_CFG
+                DCD     CPUW_BASE
+                DCD     BUSP_BASE        
+                DCD     SYSCFG_Val
+                DCD     NCACHBE0_Val
+                DCD     NCACHBE1_Val
+                DCD     SBUSCON_Val
+                ENDIF
+
+
+; Memory Controller Configuration
+                IF      MC_SETUP <> 0
+MC_CFG
+                DCD     BWSCON_Val
+                DCD     BANKCON0_Val
+                DCD     BANKCON1_Val
+                DCD     BANKCON2_Val
+                DCD     BANKCON3_Val
+                DCD     BANKCON4_Val
+                DCD     BANKCON5_Val
+                DCD     BANKCON6_Val
+                DCD     BANKCON7_Val
+                DCD     REFRESH_Val
+                DCD     BANKSIZE_Val
+                DCD     MRSRB6_Val
+                DCD     MRSRB7_Val
+                ENDIF
+
+
+; Clock Management Configuration
+                IF      CLK_SETUP <> 0
+CLK_CFG
+                DCD     CLK_BASE        
+                DCD     PLLCON_Val
+                DCD     CLKCON_Val
+                DCD     CLKSLOW_Val
+                DCD     LOCKTIME_Val
+                ENDIF
+
+
+; I/O Configuration
+                IF      PIO_SETUP <> 0
+PIO_CFG        
+                DCD     PCONA_Val
+                DCD     PCONB_Val
+                DCD     PCONC_Val
+                DCD     PCOND_Val
+                DCD     PCONE_Val
+                DCD     PCONF_Val
+                DCD     PCONG_Val
+                DCD     PUPC_Val
+                DCD     PUPD_Val
+                DCD     PUPE_Val
+                DCD     PUPF_Val
+                DCD     PUPG_Val
+                DCD     SPUCR_Val
+                ENDIF
+
+
+; Reset Handler
+
+                EXPORT  Reset_Handler
+Reset_Handler   
+
+
+                IF      SYS_SETUP <> 0
+                ADR     R8, SYS_CFG
+                LDMIA   R8, {R0-R5}
+                STMIA   R0, {R2-R4}
+                STR     R5, [R1]
+                ENDIF
+
+
+                IF      MC_SETUP <> 0
+                ADR     R14, MC_CFG
+                LDMIA   R14, {R0-R12}
+                LDR     R14, =MC_BASE
+                STMIA   R14, {R0-R12}
+                ENDIF
+
+
+                IF      CLK_SETUP <> 0
+                ADR     R8, CLK_CFG
+                LDMIA   R8, {R0-R4}
+                STR     R4, [R0, #LOCKTIME_OFS]
+                STR     R1, [R0, #PLLCON_OFS]
+                STR     R3, [R0, #CLKSLOW_OFS]
+                STR     R2, [R0, #CLKCON_OFS]
+                ENDIF
+
+
+                IF      WT_SETUP <> 0
+                LDR     R0, =WT_BASE
+                LDR     R1, =WTCON_Val
+                LDR     R2, =WTDAT_Val
+                STR     R2, [R0, #WTCNT_OFS]
+                STR     R2, [R0, #WTDAT_OFS]
+                STR     R1, [R0, #WTCON_OFS]
+                ENDIF
+
+
+                IF      PIO_SETUP <> 0
+                ADR     R14, PIO_CFG
+                LDMIA   R14, {R0-R12}
+                LDR     R14, =PIO_BASE
+
+                IF      PIOA_SETUP <> 0
+                STR     R0, [R14, #PCONA_OFS]
+                ENDIF
+
+                IF      PIOB_SETUP <> 0
+                STR     R1, [R14, #PCONB_OFS]
+                ENDIF
+
+                IF      PIOC_SETUP <> 0
+                STR     R2, [R14, #PCONC_OFS]
+                STR     R7, [R14, #PUPC_OFS]
+                ENDIF
+
+                IF      PIOD_SETUP <> 0
+                STR     R3, [R14, #PCOND_OFS]
+                STR     R8, [R14, #PUPD_OFS]
+                ENDIF
+
+                IF      PIOE_SETUP <> 0
+                STR     R4, [R14, #PCONE_OFS]
+                STR     R9, [R14, #PUPE_OFS]
+                ENDIF
+
+                IF      PIOF_SETUP <> 0
+                STR     R5, [R14, #PCONF_OFS]
+                STR     R10,[R14, #PUPF_OFS]
+                ENDIF
+
+                IF      PIOG_SETUP <> 0
+                STR     R6, [R14, #PCONG_OFS]
+                STR     R11,[R14, #PUPG_OFS]
+                ENDIF
+
+                IF      PSPU_SETUP <> 0
+                STR     R12,[R14, #SPUCR_OFS]
+                ENDIF
+
+                ENDIF
+
+
+; Setup Stack for each mode
+
+                LDR     R0, =Stack_Top
+
+;  Enter Undefined Instruction Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #UND_Stack_Size
+
+;  Enter Abort Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #ABT_Stack_Size
+
+;  Enter FIQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #FIQ_Stack_Size
+
+;  Enter IRQ Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #IRQ_Stack_Size
+
+;  Enter Supervisor Mode and set its Stack Pointer
+                MSR     CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+                MOV     SP, R0
+                SUB     R0, R0, #SVC_Stack_Size
+
+;  Enter User Mode and set its Stack Pointer
+                ; MSR     CPSR_c, #Mode_USR
+                IF      :DEF:__MICROLIB
+
+                EXPORT __initial_sp
+
+                ELSE
+
+                ; MOV     SP, R0
+                ; SUB     SL, SP, #USR_Stack_Size
+
+                ENDIF
+
+
+; Enter the C code
+
+                IMPORT  __main
+                LDR     R0, =__main
+                BX      R0
+
+				IMPORT rt_interrupt_enter
+				IMPORT rt_interrupt_leave
+				IMPORT rt_thread_switch_interrput_flag
+				IMPORT rt_interrupt_from_thread
+				IMPORT rt_interrupt_to_thread
+				IMPORT rt_hw_trap_irq
+				
+IRQ_Handler		PROC
+				EXPORT IRQ_Handler
+				STMFD	sp!, {r0-r12,lr}
+				BL	rt_interrupt_enter
+				BL	rt_hw_trap_irq
+				BL	rt_interrupt_leave
+
+				; if rt_thread_switch_interrput_flag set, jump to
+				; rt_hw_context_switch_interrupt_do and don't return
+				LDR	r0, =rt_thread_switch_interrput_flag
+				LDR	r1, [r0]
+				CMP	r1, #1
+				BEQ	rt_hw_context_switch_interrupt_do
+
+				LDMFD	sp!, {r0-r12,lr}
+				SUBS	pc, lr, #4
+				ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do	PROC
+				EXPORT rt_hw_context_switch_interrupt_do
+				MOV		r1,  #0			; clear flag
+				STR		r1,  [r0]
+
+				LDMFD	sp!, {r0-r12,lr}; reload saved registers
+				STMFD	sp!, {r0-r3}	; save r0-r3
+				MOV		r1,  sp
+				ADD		sp,  sp, #16	; restore sp
+				SUB		r2,  lr, #4		; save old task's pc to r2
+
+				MRS		r3,  spsr		; get cpsr of interrupt thread
+
+				; switch to SVC mode and no interrupt
+                MSR     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+				STMFD	sp!, {r2}		; push old task's pc
+				STMFD	sp!, {r4-r12,lr}; push old task's lr,r12-r4
+				MOV		r4,  r1			; Special optimised code below
+				MOV		r5,  r3
+				LDMFD	r4!, {r0-r3}
+				STMFD	sp!, {r0-r3}	; push old task's r3-r0
+				STMFD	sp!, {r5}		; push old task's cpsr
+				MRS		r4,  spsr
+				STMFD	sp!, {r4}		; push old task's spsr
+
+				LDR		r4,  =rt_interrupt_from_thread
+				LDR		r5,  [r4]
+				STR		sp,  [r5]		; store sp in preempted tasks's TCB
+
+				LDR		r6,  =rt_interrupt_to_thread
+				LDR		r6,  [r6]
+				LDR		sp,  [r6]		; get new task's stack pointer
+			
+				LDMFD	sp!, {r4}		; pop new task's spsr
+				MSR		spsr_cxsf, r4
+				LDMFD	sp!, {r4}		; pop new task's psr
+				MSR		cpsr_cxsf, r4
+
+				LDMFD	sp!, {r0-r12,lr,pc}	; pop new task's r0-r12,lr & pc
+				ENDP
+
+                IF      :DEF:__MICROLIB
+
+                EXPORT  __heap_base
+                EXPORT  __heap_limit
+
+                ELSE
+; User Initial Stack & Heap
+                AREA    |.text|, CODE, READONLY
+
+                IMPORT  __use_two_region_memory
+                EXPORT  __user_initial_stackheap
+__user_initial_stackheap
+
+                LDR     R0, =  Heap_Mem
+                LDR     R1, =(Stack_Mem + USR_Stack_Size)
+                LDR     R2, = (Heap_Mem +      Heap_Size)
+                LDR     R3, = Stack_Mem
+                BX      LR
+                ENDIF
+
+
+                END

+ 181 - 0
libcpu/arm/s3c44b0/trap.c

@@ -0,0 +1,181 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-09-06     XuXinming    first version
+ * 2006-09-15     Bernard      modify rt_hw_trap_irq for more effective
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "s3c44b0.h"
+
+extern unsigned char interrupt_bank0[256];
+extern unsigned char interrupt_bank1[256];
+extern unsigned char interrupt_bank2[256];
+extern unsigned char interrupt_bank3[256];
+
+extern struct rt_thread *rt_current_thread;
+
+/**
+ * @addtogroup S3C44B0
+ */
+/*@{*/
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+	rt_kprintf("Execption:\n");
+	rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+	rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+	rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+	rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+	rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+	rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("undefined instruction\n");
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+    rt_kprintf("software interrupt\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("prefetch abort\n");
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("data abort\n");
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+    rt_kprintf("not used\n");
+    rt_hw_show_register(regs);
+    rt_hw_cpu_shutdown();
+}
+
+extern rt_isr_handler_t isr_table[];
+void rt_hw_trap_irq()
+{
+	register unsigned long ispr, intstat;
+	register rt_isr_handler_t isr_func;
+
+#ifdef BSP_INT_DEBUG
+	rt_kprintf("irq coming, ");
+#endif
+	intstat = I_ISPR & 0x7ffffff;
+#ifdef BSP_INT_DEBUG
+	rt_kprintf("I_ISPR: %d\n", intstat);
+#endif
+
+	ispr = intstat;
+
+	/* to find interrupt */
+	if ( intstat & 0xff ) /* lowest 8bits */
+	{
+		intstat = interrupt_bank0[intstat & 0xff];
+		isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+	}
+	else if ( intstat & 0xff00 ) /* low 8bits */
+	{
+		intstat = interrupt_bank1[(intstat & 0xff00) >> 8];
+		isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+	}
+	else if ( intstat & 0xff0000 ) /* high 8bits */
+	{
+		intstat = interrupt_bank2[(intstat & 0xff0000) >> 16];
+		isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+	}
+	else if ( intstat & 0xff000000 ) /* highest 8bits */
+	{
+		intstat = interrupt_bank3[(intstat & 0xff000000) >> 24];
+		isr_func = (rt_isr_handler_t)isr_table[ intstat ];
+	}
+	else return;
+
+#ifdef BSP_INT_DEBUG
+	rt_kprintf("irq: %d happen\n", intstat);
+#endif
+
+	/* turn to interrupt service routine */
+	isr_func(intstat);
+
+	I_ISPC = ispr;		/* clear interrupt */
+}
+
+void rt_hw_trap_fiq()
+{
+    rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/