Browse Source

add at91sam926x porting.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1364 bbd45198-f89e-11dd-88c7-29a3b14d5316
luohui2320@gmail.com 14 years ago
parent
commit
c84fc53783

+ 22 - 0
bsp/at91sam9260/SConscript

@@ -0,0 +1,22 @@
+import rtconfig
+Import('RTT_ROOT')
+from building import *
+
+src_bsp = ['application.c', 'startup.c', 'board.c']
+src_drv = ['console.c']
+
+if GetDepend('RT_USING_LED'):
+	src_drv += ['led.c']
+
+#if GetDepend('RT_USING_DFS'):
+	#src_drv += ['sdcard.c']
+
+if GetDepend('RT_USING_LWIP'):
+	src_drv += ['macb.c']
+
+
+src	= File(src_bsp + src_drv)
+CPPPATH = [RTT_ROOT + '/bsp/at91sam9260']
+group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 37 - 0
bsp/at91sam9260/SConstruct

@@ -0,0 +1,37 @@
+import os
+import sys
+import rtconfig
+
+RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread-at91sam9260.' + rtconfig.TARGET_EXT
+
+env = Environment(tools = ['mingw'],
+	AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+	CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+	AR = rtconfig.AR, ARFLAGS = '-rc',
+	LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT)
+
+if GetDepend('RT_USING_WEBSERVER'):
+    objs = objs + SConscript(RTT_ROOT + '/components/net/webserver/SConscript', variant_dir='build/net/webserver', duplicate=0)
+
+if GetDepend('RT_USING_RTGUI'):
+    objs = objs + SConscript(RTT_ROOT + '/examples/gui/SConscript', variant_dir='build/examples/gui', duplicate=0)
+
+# libc testsuite 
+objs = objs + SConscript(RTT_ROOT + '/examples/libc/SConscript', variant_dir='build/examples/libc', duplicate=0)
+
+# build program 
+env.Program(TARGET, objs)
+
+# end building 
+EndBuilding(TARGET)

+ 101 - 0
bsp/at91sam9260/application.c

@@ -0,0 +1,101 @@
+/*
+ * File      : application.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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author		Notes
+ * 2011-01-13     weety		first version
+ */
+
+/**
+ * @addtogroup at91sam9260
+ */
+/*@{*/
+
+#include <rtthread.h>
+
+#ifdef RT_USING_LED
+#include "led.h"
+#endif
+
+#ifdef RT_USING_LED
+void rt_led_thread_entry(void* parameter)
+{
+	rt_uint8_t cnt = 0;
+	led_init();
+	while(1)
+	{
+		/* light on leds for one second */
+		rt_thread_delay(40);
+		cnt++;
+		if (cnt&0x01)
+			led_on(1);
+		else
+			led_off(1);
+		if (cnt&0x02)
+			led_on(2);
+		else
+			led_off(2);
+		if (cnt&0x04)
+			led_on(3);
+		else
+			led_off(3);
+			
+	}
+}
+#endif
+
+int rt_application_init()
+{
+#ifdef RT_USING_LED
+	rt_thread_t led_thread;
+
+#if (RT_THREAD_PRIORITY_MAX == 32)
+	
+
+	led_thread = rt_thread_create("led",
+								rt_led_thread_entry, RT_NULL,
+								512, 20, 20);
+								
+#else
+	
+
+	led_thread = rt_thread_create("led",
+								rt_led_thread_entry, RT_NULL,
+								512, 200, 20);
+								
+#endif
+
+
+	if(led_thread != RT_NULL)
+		rt_thread_startup(led_thread);
+#endif
+
+	return 0;
+}
+
+/* NFSv3 Initialization */
+#if defined(RT_USING_DFS) && defined(RT_USING_LWIP) && defined(RT_USING_DFS_NFS)
+#include <dfs_nfs.h>
+void nfs_start(void)
+{
+	nfs_init();
+
+	if (dfs_mount(RT_NULL, "/nfs", "nfs", 0, RT_NFS_HOST_EXPORT) == 0)
+	{
+		rt_kprintf("NFSv3 File System initialized!\n");
+	}
+	else
+		rt_kprintf("NFSv3 File System initialzation failed!\n");
+}
+
+#include "finsh.h"
+FINSH_FUNCTION_EXPORT(nfs_start, start net filesystem);
+#endif
+
+/*@}*/

+ 85 - 0
bsp/at91sam9260/at91sam9260_ram.ld

@@ -0,0 +1,85 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x20000000;
+
+	. = ALIGN(4);
+	.text :	
+	{
+		*(.init)
+		*(.text)
+		*(.gnu.linkonce.t*)
+		
+		/* section information for finsh shell */
+		. = ALIGN(4);
+		__fsymtab_start = .;
+		KEEP(*(FSymTab))
+		__fsymtab_end = .;
+		. = ALIGN(4);
+		__vsymtab_start = .;
+		KEEP(*(VSymTab))
+		__vsymtab_end = .;
+		. = ALIGN(4);	
+
+		/* section information for modules */
+		. = ALIGN(4);
+		__rtmsymtab_start = .;
+		KEEP(*(RTMSymTab))
+		__rtmsymtab_end = .;
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) *(.eh_frame) }
+
+	. = ALIGN(4);
+	.ctors :
+	{
+		PROVIDE(__ctors_start__ = .);
+		KEEP(*(SORT(.ctors.*)))
+		KEEP(*(.ctors))
+		PROVIDE(__ctors_end__ = .);
+	}
+
+	.dtors :
+	{
+		PROVIDE(__dtors_start__ = .);
+		KEEP(*(SORT(.dtors.*)))
+		KEEP(*(.dtors))
+		PROVIDE(__dtors_end__ = .);
+	}
+
+	. = ALIGN(4);
+	.data :
+	{
+		*(.data)
+		*(.data.*)
+		*(.gnu.linkonce.d*)
+	}
+
+	. = ALIGN(4);
+	.nobss : { *(.nobss) }
+
+	. = 0x20300000;
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	__bss_end = .;
+
+	/* stabs debugging sections. */
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+	.stab.excl 0 : { *(.stab.excl) }
+	.stab.exclstr 0 : { *(.stab.exclstr) }
+	.stab.index 0 : { *(.stab.index) }
+	.stab.indexstr 0 : { *(.stab.indexstr) }
+	.comment 0 : { *(.comment) }
+	.debug_abbrev 0 : { *(.debug_abbrev) }
+	.debug_info 0 : { *(.debug_info) }
+	.debug_line 0 : { *(.debug_line) }
+	.debug_pubnames 0 : { *(.debug_pubnames) }
+	.debug_aranges 0 : { *(.debug_aranges) }
+
+	_end = .;
+}

+ 247 - 0
bsp/at91sam9260/board.c

@@ -0,0 +1,247 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009 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
+ * 2011-01-13     weety      first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "board.h"
+
+/**
+ * @addtogroup at91sam9260
+ */
+/*@{*/
+
+
+extern void rt_hw_clock_init(void);
+extern void rt_hw_mmu_init(void);
+
+extern void rt_hw_get_clock(void);
+extern void rt_hw_set_dividor(rt_uint8_t hdivn, rt_uint8_t pdivn);
+extern void rt_hw_set_clock(rt_uint8_t sdiv, rt_uint8_t pdiv, rt_uint8_t mdiv);
+
+/*set debug serial port*/
+//#define USE_UART1
+//#define USE_UART3
+#define USE_DBGU
+
+#define DBGU	((struct uartport *)0xfffff200)
+#define UART1   ((struct uartport *)AT91SAM9260_BASE_US1)
+#define UART3	((struct uartport *)AT91SAM9260_BASE_US3)
+struct serial_int_rx uart0_int_rx;
+struct serial_device uart0 =
+{
+	//UART0,
+	DBGU,
+	//UART1,
+	//UART3,
+	&uart0_int_rx,
+	RT_NULL
+};
+struct rt_device uart0_device;
+
+
+
+/**
+ * This function will handle serial
+ */
+void rt_serial_handler(int vector)
+{
+	#ifdef USE_UART1
+	int status;
+	status = readl(AT91SAM9260_BASE_US1+AT91_US_CSR);
+	if (!(status & readl(AT91SAM9260_BASE_US1+AT91_US_IMR)))
+	{
+		return;
+	}
+	#endif
+	#ifdef USE_UART3
+	at91_sys_read(AT91_USART3+AT91_US_CSR);
+	#endif
+	rt_hw_serial_isr(&uart0_device);
+
+}
+
+/**
+ * This function will handle init uart
+ */
+void rt_hw_uart_init(void)
+{
+	rt_uint32_t  cd;
+	#ifdef USE_UART1
+	#define BAUDRATE  115200
+	//rt_uint32_t	uart_rate;
+	//at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_PIOB);
+	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_US1);
+	at91_sys_write(AT91_PIOB + PIO_IDR, (1<<6)|(1<<7));
+	at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
+	at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<7));
+	at91_sys_write(AT91_PIOB + PIO_ASR, (1<<6)|(1<<7));
+	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7));
+	writel(AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS, AT91SAM9260_BASE_US1 + AT91_US_CR);
+	writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | AT91_US_CHRL_8 | AT91_US_PAR_NONE | AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL, AT91SAM9260_BASE_US1 + AT91_US_MR);//0x100108c0
+	//at91_sys_write(AT91_USART1 + AT91_US_MR, 0x000008c0);//0x100108c0
+	cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
+	writel(cd, AT91SAM9260_BASE_US1 + AT91_US_BRGR);
+	writel(AT91_US_RXEN | AT91_US_TXEN, AT91SAM9260_BASE_US1 + AT91_US_CR);
+	
+	writel(0x1, AT91SAM9260_BASE_US1 + AT91_US_IER);
+	/* install interrupt handler */
+	rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_umask(AT91SAM9260_ID_US1);
+	#endif
+	#ifdef USE_UART3
+	#define BAUDRATE  115200
+	//rt_uint32_t	uart_rate;
+	at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_US3);
+	at91_sys_write(AT91_PIOB+0x04, (1<<10)|(1<<11));
+	at91_sys_write(AT91_PIOB+0x70, (1<<10)|(1<<11));
+	writel(AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS, AT91SAM9260_BASE_US1 + AT91_US_CR);
+	writel( AT91_US_USMODE_NORMAL | AT91_US_USCLKS_MCK | AT91_US_CHRL_8 | AT91_US_PAR_NONE | AT91_US_NBSTOP_1 | AT91_US_CHMODE_NORMAL, AT91SAM9260_BASE_US3 + AT91_US_MR);
+	cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
+	writel(cd, AT91SAM9260_BASE_US3 + AT91_US_BRGR);
+	writel(AT91_US_RXEN | AT91_US_TXEN, AT91SAM9260_BASE_US3 + AT91_US_CR);
+	
+	writel(0x1, AT91SAM9260_BASE_US3 + AT91_US_IER);
+	/* install interrupt handler */
+	rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, RT_NULL);
+	rt_hw_interrupt_umask(AT91SAM9260_ID_US3);
+	
+	#endif
+	#ifdef USE_DBGU
+	#define BAUDRATE  115200
+	//rt_uint32_t  cd;
+	at91_sys_write(AT91_PIOB + PIO_IDR, (1<<14)|(1<<15));
+	//at91_sys_write(AT91_PIOB + PIO_PUER, (1<<6));
+	at91_sys_write(AT91_PIOB + PIO_PUDR, (1<<14)|(1<<15));
+	at91_sys_write(AT91_PIOB + PIO_ASR, (1<<14)|(1<<15));
+	at91_sys_write(AT91_PIOB + PIO_PDR, (1<<14)|(1<<15));
+	at91_sys_write(AT91_PMC_PCER, 1 << AT91_ID_SYS);
+	at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RSTTX | AT91_US_RSTRX | AT91_US_RXDIS | AT91_US_TXDIS);
+	at91_sys_write(AT91_DBGU + AT91_US_IDR, 0xffffffff);
+	at91_sys_write(AT91_DBGU + AT91_US_MR, AT91_US_USMODE_NORMAL | AT91_US_PAR_NONE);
+	cd = (clk_get_rate(clk_get("mck")) / 16 + BAUDRATE/2) / BAUDRATE;
+	at91_sys_write(AT91_DBGU + AT91_US_BRGR, cd);
+	at91_sys_write(AT91_DBGU + AT91_US_CR, AT91_US_RXEN | AT91_US_TXEN);
+	
+	at91_sys_read(AT91_DBGU + AT91_US_CSR); //read for clearing interrupt
+	at91_sys_write(AT91_DBGU + AT91_US_IER, 0x1);
+	#endif
+}
+
+#define PIT_CPIV(x)	((x) & AT91_PIT_CPIV)
+#define PIT_PICNT(x)	(((x) & AT91_PIT_PICNT) >> 20)
+
+static rt_uint32_t pit_cycle;		/* write-once */
+static rt_uint32_t pit_cnt;		/* access only w/system irq blocked */
+
+/**
+ * This function will handle rtos timer
+ */
+void rt_timer_handler(int vector)
+{
+	#ifdef USE_DBGU
+	if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) {
+		//rt_kprintf("DBGU interrupt occur\n");
+		rt_serial_handler(1);
+	}
+	#endif
+	if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) {
+		unsigned nr_ticks;
+
+		/* Get number of ticks performed before irq, and ack it */
+		nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
+		rt_tick_increase();
+	}
+}
+
+static void at91sam926x_pit_reset(void)
+{
+	/* Disable timer and irqs */
+	at91_sys_write(AT91_PIT_MR, 0);
+
+	/* Clear any pending interrupts, wait for PIT to stop counting */
+	while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
+		;
+
+	/* Start PIT but don't enable IRQ */
+	//at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
+	pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
+	at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
+			| AT91_PIT_PITIEN);
+	rt_kprintf("PIT_MR=0x%08x\n", at91_sys_read(AT91_PIT_MR));
+}
+
+/*
+ * Set up both clocksource and clockevent support.
+ */
+static void at91sam926x_pit_init(void)
+{
+	rt_uint32_t	pit_rate;
+	rt_uint32_t	bits;
+
+	/*
+	 * Use our actual MCK to figure out how many MCK/16 ticks per
+	 * 1/HZ period (instead of a compile-time constant LATCH).
+	 */
+	pit_rate = clk_get_rate(clk_get("mck")) / 16;
+	rt_kprintf("pit_rate=%dHZ\n", pit_rate);
+	pit_cycle = (pit_rate + RT_TICK_PER_SECOND/2) / RT_TICK_PER_SECOND;
+
+	/* Initialize and enable the timer */
+	at91sam926x_pit_reset();
+
+}
+
+/**
+ * This function will init pit for system ticks
+ */
+ void rt_hw_timer_init()
+ {
+ 	at91sam926x_pit_init();
+
+	/* install interrupt handler */
+	rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, RT_NULL);
+	rt_hw_interrupt_umask(AT91_ID_SYS);
+
+ }
+ 
+ void at91_tc1_init()
+ {
+ 	at91_sys_write(AT91_PMC_PCER, 1<<AT91SAM9260_ID_TC0);
+ 	writel(AT91_TC_TC0XC0S_NONE | AT91_TC_TC1XC1S_NONE | AT91_TC_TC2XC2S_NONE, AT91SAM9260_BASE_TCB0 + AT91_TC_BMR);
+ 	writel(AT91_TC_CLKDIS, AT91SAM9260_BASE_TC0 + AT91_TC_CCR);
+ 	writel(AT91_TC_TIMER_CLOCK4, AT91SAM9260_BASE_TC0 + AT91_TC_CMR);
+ 	writel(0xffff, AT91SAM9260_BASE_TC0 + AT91_TC_CV);
+ }
+
+/**
+ * This function will init at91sam9260 board
+ */
+void rt_hw_board_init()
+{
+	/* initialize the system clock */
+	rt_hw_clock_init();
+
+	/* initialize uart */
+	rt_hw_uart_init();
+
+	/* initialize mmu */
+	//rt_hw_mmu_init();
+
+	/* initialize timer0 */
+	rt_hw_timer_init();
+
+}
+
+/*@}*/

+ 24 - 0
bsp/at91sam9260/board.h

@@ -0,0 +1,24 @@
+/*
+ * File      : board.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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety      add board.h to this bsp
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <at91sam926x.h>
+#include <serial.h>
+
+void rt_hw_board_init(void);
+//void rt_hw_sdcard_init(void);
+
+#endif

+ 180 - 0
bsp/at91sam9260/console.c

@@ -0,0 +1,180 @@
+#include <rtthread.h>
+
+#include <serial.h>
+
+#define RT_CONSOLE_WIDTH		240
+#define RT_CONSOLE_HEIGHT		320
+
+#define RT_CONSOLE_FONT_WIDTH	8
+#define RT_CONSOLE_FONT_HEIGHT	16
+
+#define RT_CONSOLE_COL			(RT_CONSOLE_WIDTH/RT_CONSOLE_FONT_WIDTH)
+#define RT_CONSOLE_ROW			(RT_CONSOLE_HEIGHT/RT_CONSOLE_FONT_HEIGHT)
+
+#define RT_CONSOLE_TAB			4
+
+#define RT_CONSOLE_FOREPIXEL	(0x001f)
+
+extern struct serial_device uart0;
+
+struct rt_console
+{
+	rt_uint8_t* video_ptr;
+	rt_uint8_t* font_ptr;
+
+	/* bpp and pixel of width */
+	rt_uint8_t bpp;
+	rt_uint32_t pitch;
+
+	/* current cursor */
+	rt_uint8_t current_col;
+	rt_uint8_t current_row;
+};
+struct rt_console console;
+
+void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp);
+void rt_hw_console_newline(void);
+void rt_hw_console_putc(char c);
+void rt_hw_console_clear(void);
+
+void rt_hw_console_init(rt_uint8_t* video_ptr, rt_uint8_t* font_ptr, rt_uint8_t bpp)
+{
+	rt_memset(&console, 0, sizeof(struct rt_console));
+
+	console.video_ptr = video_ptr;
+	console.font_ptr = font_ptr;
+	console.bpp = bpp;
+	console.pitch = console.bpp * RT_CONSOLE_WIDTH;
+
+	rt_hw_console_clear();
+}
+
+void rt_hw_console_putc(char c)
+{
+	switch (c)
+	{
+        case 10:
+        case 11:
+        case 12:
+        case 13:
+			/* to next line */
+            rt_hw_console_newline();
+            console.current_col = 0;
+            break;
+
+        case 9:
+            console.current_col += RT_CONSOLE_TAB;
+            break;
+
+        default:
+			{
+				rt_uint8_t* font_ptr;
+				register rt_uint32_t cursor;
+				register rt_uint32_t i, j;
+
+				if (console.current_col == RT_CONSOLE_COL)
+				{
+					rt_hw_console_newline();
+					console.current_col = 0;
+
+					rt_hw_console_putc(c);
+					return;
+				}
+
+				font_ptr = console.font_ptr + c * RT_CONSOLE_FONT_HEIGHT;
+				cursor = (console.current_row * RT_CONSOLE_FONT_HEIGHT) * console.pitch
+					+ console.current_col * RT_CONSOLE_FONT_WIDTH * console.bpp;
+
+				for (i = 0; i < RT_CONSOLE_FONT_HEIGHT; i ++ )
+				{
+					for (j = 0; j < RT_CONSOLE_FONT_WIDTH; j ++)
+					{
+						if ( ((font_ptr[i] >> (7-j)) & 0x01) != 0 )
+						{
+							/* draw a pixel */
+							rt_uint8_t *ptr = &(console.video_ptr[cursor + i * console.pitch + j * console.bpp]);
+							switch(console.bpp)
+							{
+							case 1:
+								*ptr = RT_CONSOLE_FOREPIXEL;
+								break;
+							case 2:
+								*(rt_uint16_t*)ptr = RT_CONSOLE_FOREPIXEL;
+								break;
+							case 3:
+								ptr[0] = RT_CONSOLE_FOREPIXEL & 0xff;
+								ptr[1] = (RT_CONSOLE_FOREPIXEL >> 8) & 0xff;
+								ptr[2] = (RT_CONSOLE_FOREPIXEL >> 16) & 0xff;
+								break;
+							case 4:
+								*(rt_uint32_t*)ptr = RT_CONSOLE_FOREPIXEL;
+								break;
+							}
+						}
+					}
+				}
+
+				console.current_col ++;
+			}
+			break;
+	}
+}
+
+void rt_hw_console_newline()
+{
+	console.current_row ++;
+	if (console.current_row >= RT_CONSOLE_ROW)
+	{
+		rt_uint32_t i;
+
+		/* scroll to next line */
+		for (i = 0; i < RT_CONSOLE_ROW - 1; i ++)
+		{
+			rt_memcpy(console.video_ptr + i * RT_CONSOLE_FONT_HEIGHT * console.pitch,
+				console.video_ptr + (i + 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch,
+				RT_CONSOLE_FONT_HEIGHT * console.pitch);
+		}
+
+		/* clear last line */
+		rt_memset(console.video_ptr + (RT_CONSOLE_ROW - 1) * RT_CONSOLE_FONT_HEIGHT * console.pitch,
+			0,
+			RT_CONSOLE_FONT_HEIGHT * console.pitch);
+
+		console.current_row = RT_CONSOLE_ROW - 1;
+	}
+}
+
+void rt_hw_console_clear()
+{
+	console.current_col = 0;
+	console.current_row = 0;
+
+	rt_memset(console.video_ptr, 0, RT_CONSOLE_HEIGHT * console.pitch);
+}
+
+/* write one character to serial, must not trigger interrupt */
+void rt_hw_serial_putc(const char c)
+{
+	/*
+		to be polite with serial console add a line feed
+		to the carriage return character
+	*/
+	if (c=='\n')rt_hw_serial_putc('\r');
+
+	while (!(uart0.uart_device->USART_CSR & TXRDY));
+	uart0.uart_device->USART_THR = (c & 0x1FF);
+}
+
+/**
+ * This function is used by rt_kprintf to display a string on console.
+ *
+ * @param str the displayed string
+ */
+void rt_hw_console_output(const char* str)
+{
+	while (*str)
+	{
+		rt_hw_serial_putc(*str++);
+	}
+}
+

+ 63 - 0
bsp/at91sam9260/led.c

@@ -0,0 +1,63 @@
+/*
+ * File      : led.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
+ * 2011-01-13     weety      first version
+ */
+
+#include <rtthread.h>
+#include <at91sam926x.h>
+#include "led.h"
+
+void led_init(void)
+{
+	at91_sys_write(AT91_PIOC, (1<<8)|(1<<11)|(1<<6));
+	at91_sys_write(AT91_PIOC+0x10, (1<<8)|(1<<11)|(1<<6));
+	at91_sys_write(AT91_PIOC+0x64, (1<<8)|(1<<11)|(1<<6));
+	at91_sys_write(AT91_PIOC+0x30, (1<<8)|(1<<11)|(1<<6));
+}
+
+void led_on(int num)
+{
+	switch(num)
+	{
+		case 1:
+			at91_sys_write(AT91_PIOC+0x34, 1<<8);
+			break;
+		case 2:
+			at91_sys_write(AT91_PIOC+0x34, 1<<11);
+			break;
+		case 3:
+			at91_sys_write(AT91_PIOC+0x34, 1<<6);
+			break;
+		default:
+			break;
+	}
+	
+}
+
+void led_off(int num)
+{
+	switch(num)
+	{
+		case 1:
+			at91_sys_write(AT91_PIOC+0x30, 1<<8);
+			break;
+		case 2:
+			at91_sys_write(AT91_PIOC+0x30, 1<<11);
+			break;
+		case 3:
+			at91_sys_write(AT91_PIOC+0x30, 1<<6);
+			break;
+		default:
+			break;
+	}
+	//at91_sys_write(AT91_PIOC+0x30, 1<<8);
+}

+ 8 - 0
bsp/at91sam9260/led.h

@@ -0,0 +1,8 @@
+#ifndef __LED_H__
+#define __LED_H__
+
+void led_init(void);
+void led_on(int num);
+void led_off(int num);
+
+#endif

+ 239 - 0
bsp/at91sam9260/rtconfig.h

@@ -0,0 +1,239 @@
+/* RT-Thread config file */
+#ifndef __RTTHREAD_CFG_H__
+#define __RTTHREAD_CFG_H__
+
+/* RT_NAME_MAX*/
+#define RT_NAME_MAX	32
+
+/* RT_ALIGN_SIZE*/
+#define RT_ALIGN_SIZE	4
+
+/* PRIORITY_MAX */
+#define RT_THREAD_PRIORITY_MAX	256
+
+/* Tick per Second */
+#define RT_TICK_PER_SECOND	100
+
+/* SECTION: RT_DEBUG */
+/* Thread Debug */
+#define RT_DEBUG
+//#define SCHEDULER_DEBUG
+/* #define RT_THREAD_DEBUG */
+
+#define RT_USING_OVERFLOW_CHECK
+
+/* Using Hook */
+#define RT_USING_HOOK
+
+/* Using Software Timer */
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO		8
+#define RT_TIMER_THREAD_STACK_SIZE	512
+#define RT_TIMER_TICK_PER_SECOND	10
+
+/* SECTION: IPC */
+/* Using Semaphore */
+#define RT_USING_SEMAPHORE
+
+/* Using Mutex */
+#define RT_USING_MUTEX
+
+/* Using Event */
+#define RT_USING_EVENT
+
+/* Using MailBox */
+#define RT_USING_MAILBOX
+
+/* Using Message Queue */
+#define RT_USING_MESSAGEQUEUE
+
+/* SECTION: Memory Management */
+/* Using Memory Pool Management*/
+#define RT_USING_MEMPOOL
+
+/* Using Dynamic Heap Management */
+#define RT_USING_HEAP
+
+/* Using Small MM */
+/* #define RT_USING_SMALL_MEM */
+
+/* Using SLAB Allocator */
+#define RT_USING_SLAB
+
+/* SECTION: Device System */
+/* Using Device System */
+#define RT_USING_DEVICE
+
+/* Using Module System */
+#define RT_USING_MODULE
+#define RT_USING_LIBDL
+
+/* SECTION: Console options */
+#define RT_USING_CONSOLE
+/* the buffer size of console */
+#define RT_CONSOLEBUF_SIZE	128
+
+/* SECTION: finsh, a C-Express shell */
+/* Using FinSH as Shell*/
+#define RT_USING_FINSH
+/* Using symbol table */
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_STACK_SIZE 4096
+
+/* SECTION: the runtime libc library */
+/* the runtime libc library */
+#define RT_USING_NEWLIB
+#define RT_USING_PTHREADS
+
+/* SECTION: C++ support */
+/* Using C++ support */
+/* #define RT_USING_CPLUSPLUS */
+
+/* SECTION: Device filesystem support */
+/* using DFS support */
+#define RT_USING_DFS
+#define RT_USING_DFS_ELMFAT
+/* use long file name feature 			*/
+#define RT_DFS_ELM_USE_LFN			1
+/* the max number of file length 		*/
+#define RT_DFS_ELM_MAX_LFN			128
+/* #define RT_USING_DFS_YAFFS2 */
+#define RT_USING_DFS_DEVFS
+
+#define RT_USING_DFS_NFS
+#define RT_NFS_HOST_EXPORT		"192.168.1.5:/"
+
+#define DFS_USING_WORKDIR
+
+/* the max number of mounted filesystem */
+#define DFS_FILESYSTEMS_MAX		4
+/* the max number of opened files 		*/
+#define DFS_FD_MAX					16
+/* the max number of cached sector 		*/
+#define DFS_CACHE_MAX_NUM   		4
+
+/* Enable freemodbus protocol stack*/
+/* #define RT_USING_MODBUS */
+
+//#define RT_USING_LED
+
+/* SECTION: lwip, a lightweight TCP/IP protocol stack */
+/* Using lightweight TCP/IP protocol stack */
+//#define RT_USING_LWIP
+#define RT_LWIP_DNS
+
+/* Trace LwIP protocol */
+// #define RT_LWIP_DEBUG 
+
+/* Enable ICMP protocol */
+#define RT_LWIP_ICMP
+
+/* Enable IGMP protocol */
+#define RT_LWIP_IGMP
+
+/* Enable UDP protocol */
+#define RT_LWIP_UDP
+
+/* Enable TCP protocol */
+#define RT_LWIP_TCP
+
+/* the number of simulatenously active TCP connections*/
+#define RT_LWIP_TCP_PCB_NUM	5
+
+/* TCP sender buffer space */
+#define RT_LWIP_TCP_SND_BUF	1024*10
+
+/* TCP receive window. */
+#define RT_LWIP_TCP_WND	1024
+
+/* Enable SNMP protocol */
+/* #define RT_LWIP_SNMP */
+
+/* Using DHCP */
+/* #define RT_LWIP_DHCP */
+
+#define RT_LWIP_DNS
+
+/* ip address of target */
+#define RT_LWIP_IPADDR0	192
+#define RT_LWIP_IPADDR1	168
+#define RT_LWIP_IPADDR2	1
+#define RT_LWIP_IPADDR3	30
+
+/* gateway address of target */
+#define RT_LWIP_GWADDR0	192
+#define RT_LWIP_GWADDR1	168
+#define RT_LWIP_GWADDR2	1
+#define RT_LWIP_GWADDR3	1
+
+/* mask address of target */
+#define RT_LWIP_MSKADDR0	255
+#define RT_LWIP_MSKADDR1	255
+#define RT_LWIP_MSKADDR2	255
+#define RT_LWIP_MSKADDR3	0
+
+/* the number of blocks for pbuf */
+#define RT_LWIP_PBUF_NUM	16
+
+/* the number of simultaneously queued TCP */
+#define RT_LWIP_TCP_SEG_NUM    40
+
+/* thread priority of tcpip thread */
+#define RT_LWIP_TCPTHREAD_PRIORITY	128
+
+/* mail box size of tcpip thread to wait for */
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE	32
+
+/* thread stack size of tcpip thread */
+#define RT_LWIP_TCPTHREAD_STACKSIZE	4096
+
+/* thread priority of ethnetif thread */
+#define RT_LWIP_ETHTHREAD_PRIORITY	144
+
+/* mail box size of ethnetif thread to wait for */
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE	32
+
+/* thread stack size of ethnetif thread */
+#define RT_LWIP_ETHTHREAD_STACKSIZE	1024
+
+
+/* SECTION: RTGUI support */
+/* using RTGUI support */
+/* #define RT_USING_RTGUI */
+
+/* name length of RTGUI object */
+//#define RTGUI_NAME_MAX		16
+/* support 16 weight font */
+//#define RTGUI_USING_FONT16
+/* support 16 weight font */
+//#define RTGUI_USING_FONT12
+/* support Chinese font */
+//#define RTGUI_USING_FONTHZ
+/* use DFS as file interface */
+//#define RTGUI_USING_DFS_FILERW
+/* use font file as Chinese font */
+/* #define RTGUI_USING_HZ_FILE */
+/* use Chinese bitmap font */
+//#define RTGUI_USING_HZ_BMP
+/* use small size in RTGUI */
+/* #define RTGUI_USING_SMALL_SIZE */
+/* use mouse cursor */
+/* #define RTGUI_USING_MOUSE_CURSOR */
+
+/* SECTION: FTK support */
+/* using FTK support */
+/* #define RT_USING_FTK */
+
+/*
+ * Note on FTK:
+ * 
+ * FTK depends :
+ * #define RT_USING_NEWLIB
+ * #define DFS_USING_WORKDIR
+ * 
+ * And the maximal length must great than 64
+ * #define RT_DFS_ELM_MAX_LFN	128
+ */
+
+#endif

+ 82 - 0
bsp/at91sam9260/rtconfig.py

@@ -0,0 +1,82 @@
+
+# toolchains options
+ARCH     = 'arm'
+CPU      = 'at91sam926x'
+TextBase = '0x20000000'
+
+CROSS_TOOL 	= 'gcc'
+
+if  CROSS_TOOL == 'gcc':
+	PLATFORM 	= 'gcc'
+	EXEC_PATH 	= '/opt/arm-2010q1/bin/'
+elif CROSS_TOOL == 'keil':
+	PLATFORM 	= 'armcc'
+	EXEC_PATH 	= 'E:/Keil'
+#BUILD = 'debug'
+BUILD = 'release'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX = 'arm-none-eabi-'
+    #PREFIX = 'arm-none-linux-gnueabi-'
+    CC = PREFIX + 'gcc'
+    AS = PREFIX + 'gcc'
+    AR = PREFIX + 'ar'
+    LINK = PREFIX + 'gcc'
+    TARGET_EXT = 'axf'
+    SIZE = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY = PREFIX + 'objcopy'
+
+    DEVICE = ' -mcpu=arm926ej-s'
+    CFLAGS = DEVICE
+    AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' + ' -DTEXT_BASE=' + TextBase
+    LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread_at91sam9260.map,-cref,-u,_start -T at91sam9260_ram.ld' + ' -Ttext ' + TextBase
+
+    CPATH = ''
+    LPATH = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -gdwarf-2'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+
+elif PLATFORM == 'armcc':
+    # toolchains
+    CC = 'armcc'
+    AS = 'armasm'
+    AR = 'armar'
+    LINK = 'armlink'
+    TARGET_EXT = 'axf'
+
+    DEVICE = ' --device DARMSS9'
+    CFLAGS = DEVICE + ' --apcs=interwork --diag_suppress=870'
+    AFLAGS = DEVICE
+    LFLAGS = DEVICE + ' --strict --info sizes --info totals --info unused --info veneers --list rtthread-at91sam9260.map --ro-base 0x20000000 --entry Entry_Point --first Entry_Point'
+
+    CFLAGS += ' -I"' + EXEC_PATH + '/ARM/RV31/INC"'
+    LFLAGS += ' --libpath "' + EXEC_PATH + '/ARM/RV31/LIB"'
+
+    EXEC_PATH += '/arm/bin40/'
+
+    if BUILD == 'debug':
+        CFLAGS += ' -g -O0'
+        AFLAGS += ' -g'
+    else:
+        CFLAGS += ' -O2'
+
+    POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET'
+
+elif PLATFORM == 'iar':
+    # toolchains
+    CC = 'armcc'
+    AS = 'armasm'
+    AR = 'armar'
+    LINK = 'armlink'
+
+    CFLAGS = ''
+    AFLAGS = ''
+    LFLAGS = ''

+ 150 - 0
bsp/at91sam9260/startup.c

@@ -0,0 +1,150 @@
+/*
+ * File      : startup.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
+ * 2011-01-13     weety      first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include <at91sam926x.h>
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#endif
+
+extern void rt_hw_interrupt_init(void);
+extern void rt_hw_board_init(void);
+extern void rt_serial_init(void);
+extern void rt_system_timer_init(void);
+extern void rt_system_scheduler_init(void);
+extern void rt_thread_idle_init(void);
+extern void rt_hw_cpu_icache_enable(void);
+extern void rt_show_version(void);
+extern void rt_system_heap_init(void*, void*);
+extern void rt_hw_finsh_init(void);
+extern void rt_application_init(void);
+
+extern struct serial_device uart0;
+extern struct rt_device uart0_device;
+
+/**
+ * @addtogroup at91sam9260
+ */
+
+/*@{*/
+#if defined(__CC_ARM)
+	extern int Image$$ER_ZI$$ZI$$Base;
+	extern int Image$$ER_ZI$$ZI$$Length;
+	extern int Image$$ER_ZI$$ZI$$Limit;
+#elif (defined (__GNUC__))
+	rt_uint8_t _irq_stack_start[1024];
+	rt_uint8_t _fiq_stack_start[1024];
+	rt_uint8_t _undefined_stack_start[512];
+	rt_uint8_t _abort_stack_start[512];
+	rt_uint8_t _svc_stack_start[1024] SECTION(".nobss");
+	extern unsigned char __bss_start;
+	extern unsigned char __bss_end;
+#endif
+
+#ifdef RT_USING_FINSH
+extern void finsh_system_init(void);
+#endif
+
+
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+	rt_uint32_t UNUSED level;
+
+	/* disable interrupt first */
+	level = rt_hw_interrupt_disable();
+	/* enable cpu cache */
+	rt_hw_cpu_icache_enable();
+	rt_hw_cpu_dcache_enable();
+
+	/* initialize hardware interrupt */
+	rt_hw_interrupt_init();
+
+	/* initialize board */
+	rt_hw_board_init();
+
+	/* show version */
+	rt_show_version();
+	
+	/* initialize tick */
+	rt_system_tick_init();
+
+	/* initialize kernel object */
+	rt_system_object_init();
+
+	/* initialize timer system */
+	rt_system_timer_init();
+
+	/* initialize heap memory system */
+#ifdef __CC_ARM
+	rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)0x24000000);
+#else
+	rt_system_heap_init((void*)&__bss_end, (void*)0x23f00000);
+#endif
+
+#ifdef RT_USING_MODULE
+	/* initialize module system*/
+	rt_system_module_init();
+#endif
+
+	/* initialize scheduler system */
+	rt_system_scheduler_init();
+
+#ifdef RT_USING_DEVICE
+	/* register uart1 */
+	rt_hw_serial_register(&uart0_device, "uart0",
+		RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_INT_RX,
+		&uart0); 
+
+#ifdef RT_USING_DFS
+	//rt_hw_sdcard_init();
+#endif
+
+#ifdef RT_USING_LWIP
+	rt_hw_macb_init();
+#endif
+
+	/*init all registed devices */
+	rt_device_init_all();
+#endif
+
+	/* initialize application */
+	rt_application_init();
+
+#ifdef RT_USING_FINSH
+	/* initialize finsh */
+	finsh_system_init();
+#ifdef RT_USING_DEVICE
+	finsh_set_device("uart0");
+#endif
+#endif
+
+	/* initialize system timer thread */
+	rt_system_timer_thread_init();
+
+	/* initialize idle thread */
+	rt_thread_idle_init();
+
+	/* start scheduler */
+	rt_system_scheduler_start();
+
+	/* never reach here */
+	return ;
+}
+
+/*@}*/

+ 61 - 0
libcpu/arm/at91sam926x/at91_aic.h

@@ -0,0 +1,61 @@
+/*
+ * File      : at91_aic.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_AIC_H
+#define AT91_AIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_AIC_SMR(n)		(AT91_AIC + ((n) * 4))	/* Source Mode Registers 0-31 */
+#define		AT91_AIC_PRIOR		(7 << 0)		/* Priority Level */
+#define		AT91_AIC_SRCTYPE	(3 << 5)		/* Interrupt Source Type */
+#define			AT91_AIC_SRCTYPE_LOW		(0 << 5)
+#define			AT91_AIC_SRCTYPE_FALLING	(1 << 5)
+#define			AT91_AIC_SRCTYPE_HIGH		(2 << 5)
+#define			AT91_AIC_SRCTYPE_RISING		(3 << 5)
+
+#define AT91_AIC_SVR(n)		(AT91_AIC + 0x80 + ((n) * 4))	/* Source Vector Registers 0-31 */
+#define AT91_AIC_IVR		(AT91_AIC + 0x100)	/* Interrupt Vector Register */
+#define AT91_AIC_FVR		(AT91_AIC + 0x104)	/* Fast Interrupt Vector Register */
+#define AT91_AIC_ISR		(AT91_AIC + 0x108)	/* Interrupt Status Register */
+#define		AT91_AIC_IRQID		(0x1f << 0)		/* Current Interrupt Identifier */
+
+#define AT91_AIC_IPR		(AT91_AIC + 0x10c)	/* Interrupt Pending Register */
+#define AT91_AIC_IMR		(AT91_AIC + 0x110)	/* Interrupt Mask Register */
+#define AT91_AIC_CISR		(AT91_AIC + 0x114)	/* Core Interrupt Status Register */
+#define		AT91_AIC_NFIQ		(1 << 0)		/* nFIQ Status */
+#define		AT91_AIC_NIRQ		(1 << 1)		/* nIRQ Status */
+
+#define AT91_AIC_IECR		(AT91_AIC + 0x120)	/* Interrupt Enable Command Register */
+#define AT91_AIC_IDCR		(AT91_AIC + 0x124)	/* Interrupt Disable Command Register */
+#define AT91_AIC_ICCR		(AT91_AIC + 0x128)	/* Interrupt Clear Command Register */
+#define AT91_AIC_ISCR		(AT91_AIC + 0x12c)	/* Interrupt Set Command Register */
+#define AT91_AIC_EOICR		(AT91_AIC + 0x130)	/* End of Interrupt Command Register */
+#define AT91_AIC_SPU		(AT91_AIC + 0x134)	/* Spurious Interrupt Vector Register */
+#define AT91_AIC_DCR		(AT91_AIC + 0x138)	/* Debug Control Register */
+#define		AT91_AIC_DCR_PROT	(1 << 0)		/* Protection Mode */
+#define		AT91_AIC_DCR_GMSK	(1 << 1)		/* General Mask */
+
+#define AT91_AIC_FFER		(AT91_AIC + 0x140)	/* Fast Forcing Enable Register [SAM9 only] */
+#define AT91_AIC_FFDR		(AT91_AIC + 0x144)	/* Fast Forcing Disable Register [SAM9 only] */
+#define AT91_AIC_FFSR		(AT91_AIC + 0x148)	/* Fast Forcing Status Register [SAM9 only] */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 57 - 0
libcpu/arm/at91sam926x/at91_pio.h

@@ -0,0 +1,57 @@
+/*
+ * File      : at91_pio.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_PIO_H
+#define AT91_PIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PIO_PER		0x00	/* Enable Register */
+#define PIO_PDR		0x04	/* Disable Register */
+#define PIO_PSR		0x08	/* Status Register */
+#define PIO_OER		0x10	/* Output Enable Register */
+#define PIO_ODR		0x14	/* Output Disable Register */
+#define PIO_OSR		0x18	/* Output Status Register */
+#define PIO_IFER	0x20	/* Glitch Input Filter Enable */
+#define PIO_IFDR	0x24	/* Glitch Input Filter Disable */
+#define PIO_IFSR	0x28	/* Glitch Input Filter Status */
+#define PIO_SODR	0x30	/* Set Output Data Register */
+#define PIO_CODR	0x34	/* Clear Output Data Register */
+#define PIO_ODSR	0x38	/* Output Data Status Register */
+#define PIO_PDSR	0x3c	/* Pin Data Status Register */
+#define PIO_IER		0x40	/* Interrupt Enable Register */
+#define PIO_IDR		0x44	/* Interrupt Disable Register */
+#define PIO_IMR		0x48	/* Interrupt Mask Register */
+#define PIO_ISR		0x4c	/* Interrupt Status Register */
+#define PIO_MDER	0x50	/* Multi-driver Enable Register */
+#define PIO_MDDR	0x54	/* Multi-driver Disable Register */
+#define PIO_MDSR	0x58	/* Multi-driver Status Register */
+#define PIO_PUDR	0x60	/* Pull-up Disable Register */
+#define PIO_PUER	0x64	/* Pull-up Enable Register */
+#define PIO_PUSR	0x68	/* Pull-up Status Register */
+#define PIO_ASR		0x70	/* Peripheral A Select Register */
+#define PIO_BSR		0x74	/* Peripheral B Select Register */
+#define PIO_ABSR	0x78	/* AB Status Register */
+#define PIO_OWER	0xa0	/* Output Write Enable Register */
+#define PIO_OWDR	0xa4	/* Output Write Disable Register */
+#define PIO_OWSR	0xa8	/* Output Write Status Register */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 40 - 0
libcpu/arm/at91sam926x/at91_pit.h

@@ -0,0 +1,40 @@
+/*
+ * File      : at91_pit.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_PIT_H
+#define AT91_PIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_PIT_MR		(AT91_PIT + 0x00)	/* Mode Register */
+#define		AT91_PIT_PITIEN		(1 << 25)		/* Timer Interrupt Enable */
+#define		AT91_PIT_PITEN		(1 << 24)		/* Timer Enabled */
+#define		AT91_PIT_PIV		(0xfffff)		/* Periodic Interval Value */
+
+#define AT91_PIT_SR		(AT91_PIT + 0x04)	/* Status Register */
+#define		AT91_PIT_PITS		(1 << 0)		/* Timer Status */
+
+#define AT91_PIT_PIVR		(AT91_PIT + 0x08)	/* Periodic Interval Value Register */
+#define AT91_PIT_PIIR		(AT91_PIT + 0x0c)	/* Periodic Interval Image Register */
+#define		AT91_PIT_PICNT		(0xfff << 20)		/* Interval Counter */
+#define		AT91_PIT_CPIV		(0xfffff)		/* Inverval Value */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 141 - 0
libcpu/arm/at91sam926x/at91_pmc.h

@@ -0,0 +1,141 @@
+/*
+ * File      : at91_pmc.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_PMC_H
+#define AT91_PMC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	AT91_PMC_SCER		(AT91_PMC + 0x00)	/* System Clock Enable Register */
+#define	AT91_PMC_SCDR		(AT91_PMC + 0x04)	/* System Clock Disable Register */
+
+#define	AT91_PMC_SCSR		(AT91_PMC + 0x08)	/* System Clock Status Register */
+#define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
+#define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
+#define		AT91RM9200_PMC_MCKUDP	(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
+#define		AT91CAP9_PMC_DDR	(1 <<  2)		/* DDR Clock [CAP9 revC & some SAM9 only] */
+#define		AT91RM9200_PMC_UHP	(1 <<  4)		/* USB Host Port Clock [AT91RM9200 only] */
+#define		AT91SAM926x_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91SAM926x only] */
+#define		AT91CAP9_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91CAP9 only] */
+#define		AT91SAM926x_PMC_UDP	(1 <<  7)		/* USB Devcice Port Clock [AT91SAM926x only] */
+#define		AT91_PMC_PCK0		(1 <<  8)		/* Programmable Clock 0 */
+#define		AT91_PMC_PCK1		(1 <<  9)		/* Programmable Clock 1 */
+#define		AT91_PMC_PCK2		(1 << 10)		/* Programmable Clock 2 */
+#define		AT91_PMC_PCK3		(1 << 11)		/* Programmable Clock 3 */
+#define		AT91_PMC_PCK4		(1 << 12)		/* Programmable Clock 4 [AT572D940HF only] */
+#define		AT91_PMC_HCK0		(1 << 16)		/* AHB Clock (USB host) [AT91SAM9261 only] */
+#define		AT91_PMC_HCK1		(1 << 17)		/* AHB Clock (LCD) [AT91SAM9261 only] */
+
+#define	AT91_PMC_PCER		(AT91_PMC + 0x10)	/* Peripheral Clock Enable Register */
+#define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
+#define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
+
+#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [some SAM9, CAP9] */
+#define		AT91_PMC_UPLLEN		(1   << 16)		/* UTMI PLL Enable */
+#define		AT91_PMC_UPLLCOUNT	(0xf << 20)		/* UTMI PLL Start-up Time */
+#define		AT91_PMC_BIASEN		(1   << 24)		/* UTMI BIAS Enable */
+#define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI BIAS Start-up Time */
+
+#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
+#define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
+#define		AT91_PMC_OSCBYPASS	(1    << 1)		/* Oscillator Bypass [SAM9x, CAP9] */
+#define		AT91_PMC_OSCOUNT	(0xff << 8)		/* Main Oscillator Start-up Time */
+
+#define	AT91_CKGR_MCFR		(AT91_PMC + 0x24)	/* Main Clock Frequency Register */
+#define		AT91_PMC_MAINF		(0xffff <<  0)		/* Main Clock Frequency */
+#define		AT91_PMC_MAINRDY	(1	<< 16)		/* Main Clock Ready */
+
+#define	AT91_CKGR_PLLAR		(AT91_PMC + 0x28)	/* PLL A Register */
+#define	AT91_CKGR_PLLBR		(AT91_PMC + 0x2c)	/* PLL B Register */
+#define		AT91_PMC_DIV		(0xff  <<  0)		/* Divider */
+#define		AT91_PMC_PLLCOUNT	(0x3f  <<  8)		/* PLL Counter */
+#define		AT91_PMC_OUT		(3     << 14)		/* PLL Clock Frequency Range */
+#define		AT91_PMC_MUL		(0x7ff << 16)		/* PLL Multiplier */
+#define		AT91_PMC_USBDIV		(3     << 28)		/* USB Divisor (PLLB only) */
+#define			AT91_PMC_USBDIV_1		(0 << 28)
+#define			AT91_PMC_USBDIV_2		(1 << 28)
+#define			AT91_PMC_USBDIV_4		(2 << 28)
+#define		AT91_PMC_USB96M		(1     << 28)		/* Divider by 2 Enable (PLLB only) */
+
+#define	AT91_PMC_MCKR		(AT91_PMC + 0x30)	/* Master Clock Register */
+#define		AT91_PMC_CSS		(3 <<  0)		/* Master Clock Selection */
+#define			AT91_PMC_CSS_SLOW		(0 << 0)
+#define			AT91_PMC_CSS_MAIN		(1 << 0)
+#define			AT91_PMC_CSS_PLLA		(2 << 0)
+#define			AT91_PMC_CSS_PLLB		(3 << 0)
+#define			AT91_PMC_CSS_UPLL		(3 << 0)	/* [some SAM9 only] */
+#define		AT91_PMC_PRES		(7 <<  2)		/* Master Clock Prescaler */
+#define			AT91_PMC_PRES_1			(0 << 2)
+#define			AT91_PMC_PRES_2			(1 << 2)
+#define			AT91_PMC_PRES_4			(2 << 2)
+#define			AT91_PMC_PRES_8			(3 << 2)
+#define			AT91_PMC_PRES_16		(4 << 2)
+#define			AT91_PMC_PRES_32		(5 << 2)
+#define			AT91_PMC_PRES_64		(6 << 2)
+#define		AT91_PMC_MDIV		(3 <<  8)		/* Master Clock Division */
+#define			AT91RM9200_PMC_MDIV_1		(0 << 8)	/* [AT91RM9200 only] */
+#define			AT91RM9200_PMC_MDIV_2		(1 << 8)
+#define			AT91RM9200_PMC_MDIV_3		(2 << 8)
+#define			AT91RM9200_PMC_MDIV_4		(3 << 8)
+#define			AT91SAM9_PMC_MDIV_1		(0 << 8)	/* [SAM9,CAP9 only] */
+#define			AT91SAM9_PMC_MDIV_2		(1 << 8)
+#define			AT91SAM9_PMC_MDIV_4		(2 << 8)
+#define			AT91SAM9_PMC_MDIV_6		(3 << 8)	/* [some SAM9 only] */
+#define			AT91SAM9_PMC_MDIV_3		(3 << 8)	/* [some SAM9 only] */
+#define		AT91_PMC_PDIV		(1 << 12)		/* Processor Clock Division [some SAM9 only] */
+#define			AT91_PMC_PDIV_1			(0 << 12)
+#define			AT91_PMC_PDIV_2			(1 << 12)
+#define		AT91_PMC_PLLADIV2	(1 << 12)		/* PLLA divisor by 2 [some SAM9 only] */
+#define			AT91_PMC_PLLADIV2_OFF		(0 << 12)
+#define			AT91_PMC_PLLADIV2_ON		(1 << 12)
+
+#define	AT91_PMC_USB		(AT91_PMC + 0x38)	/* USB Clock Register [some SAM9 only] */
+#define		AT91_PMC_USBS		(0x1 <<  0)		/* USB OHCI Input clock selection */
+#define			AT91_PMC_USBS_PLLA		(0 << 0)
+#define			AT91_PMC_USBS_UPLL		(1 << 0)
+#define		AT91_PMC_OHCIUSBDIV	(0xF <<  8)		/* Divider for USB OHCI Clock */
+
+#define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-N Registers */
+#define		AT91_PMC_CSSMCK		(0x1 <<  8)		/* CSS or Master Clock Selection */
+#define			AT91_PMC_CSSMCK_CSS		(0 << 8)
+#define			AT91_PMC_CSSMCK_MCK		(1 << 8)
+
+#define	AT91_PMC_IER		(AT91_PMC + 0x60)	/* Interrupt Enable Register */
+#define	AT91_PMC_IDR		(AT91_PMC + 0x64)	/* Interrupt Disable Register */
+#define	AT91_PMC_SR		(AT91_PMC + 0x68)	/* Status Register */
+#define		AT91_PMC_MOSCS		(1 <<  0)		/* MOSCS Flag */
+#define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
+#define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
+#define		AT91_PMC_MCKRDY		(1 <<  3)		/* Master Clock */
+#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [some SAM9, AT91CAP9 only] */
+#define		AT91_PMC_OSCSEL		(1 <<  7)		/* Slow Clock Oscillator [AT91CAP9 revC only] */
+#define		AT91_PMC_PCK0RDY	(1 <<  8)		/* Programmable Clock 0 */
+#define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
+#define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */
+#define		AT91_PMC_PCK3RDY	(1 << 11)		/* Programmable Clock 3 */
+#define	AT91_PMC_IMR		(AT91_PMC + 0x6c)	/* Interrupt Mask Register */
+
+#define AT91_PMC_PROT		(AT91_PMC + 0xe4)	/* Protect Register [AT91CAP9 revC only] */
+#define		AT91_PMC_PROTKEY	0x504d4301		/* Activation Code */
+
+#define AT91_PMC_VER		(AT91_PMC + 0xfc)	/* PMC Module Version [AT91CAP9 only] */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 49 - 0
libcpu/arm/at91sam926x/at91_rstc.h

@@ -0,0 +1,49 @@
+/*
+ * File      : at91_rstc.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_RSTC_H
+#define AT91_RSTC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_RSTC_CR		(AT91_RSTC + 0x00)	/* Reset Controller Control Register */
+#define		AT91_RSTC_PROCRST	(1 << 0)		/* Processor Reset */
+#define		AT91_RSTC_PERRST	(1 << 2)		/* Peripheral Reset */
+#define		AT91_RSTC_EXTRST	(1 << 3)		/* External Reset */
+#define		AT91_RSTC_KEY		(0xa5 << 24)		/* KEY Password */
+
+#define AT91_RSTC_SR		(AT91_RSTC + 0x04)	/* Reset Controller Status Register */
+#define		AT91_RSTC_URSTS		(1 << 0)		/* User Reset Status */
+#define		AT91_RSTC_RSTTYP	(7 << 8)		/* Reset Type */
+#define			AT91_RSTC_RSTTYP_GENERAL	(0 << 8)
+#define			AT91_RSTC_RSTTYP_WAKEUP		(1 << 8)
+#define			AT91_RSTC_RSTTYP_WATCHDOG	(2 << 8)
+#define			AT91_RSTC_RSTTYP_SOFTWARE	(3 << 8)
+#define			AT91_RSTC_RSTTYP_USER	(4 << 8)
+#define		AT91_RSTC_NRSTL		(1 << 16)		/* NRST Pin Level */
+#define		AT91_RSTC_SRCMP		(1 << 17)		/* Software Reset Command in Progress */
+
+#define AT91_RSTC_MR		(AT91_RSTC + 0x08)	/* Reset Controller Mode Register */
+#define		AT91_RSTC_URSTEN	(1 << 0)		/* User Reset Enable */
+#define		AT91_RSTC_URSTIEN	(1 << 4)		/* User Reset Interrupt Enable */
+#define		AT91_RSTC_ERSTL		(0xf << 8)		/* External Reset Length */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 135 - 0
libcpu/arm/at91sam926x/at91_serial.h

@@ -0,0 +1,135 @@
+/*
+ * File      : at91_serial.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_SERIAL_H
+#define AT91_SERIAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_US_CR		0x00			/* Control Register */
+#define		AT91_US_RSTRX		(1 <<  2)		/* Reset Receiver */
+#define		AT91_US_RSTTX		(1 <<  3)		/* Reset Transmitter */
+#define		AT91_US_RXEN		(1 <<  4)		/* Receiver Enable */
+#define		AT91_US_RXDIS		(1 <<  5)		/* Receiver Disable */
+#define		AT91_US_TXEN		(1 <<  6)		/* Transmitter Enable */
+#define		AT91_US_TXDIS		(1 <<  7)		/* Transmitter Disable */
+#define		AT91_US_RSTSTA		(1 <<  8)		/* Reset Status Bits */
+#define		AT91_US_STTBRK		(1 <<  9)		/* Start Break */
+#define		AT91_US_STPBRK		(1 << 10)		/* Stop Break */
+#define		AT91_US_STTTO		(1 << 11)		/* Start Time-out */
+#define		AT91_US_SENDA		(1 << 12)		/* Send Address */
+#define		AT91_US_RSTIT		(1 << 13)		/* Reset Iterations */
+#define		AT91_US_RSTNACK	(1 << 14)		/* Reset Non Acknowledge */
+#define		AT91_US_RETTO		(1 << 15)		/* Rearm Time-out */
+#define		AT91_US_DTREN		(1 << 16)		/* Data Terminal Ready Enable [AT91RM9200 only] */
+#define		AT91_US_DTRDIS		(1 << 17)		/* Data Terminal Ready Disable [AT91RM9200 only] */
+#define		AT91_US_RTSEN		(1 << 18)		/* Request To Send Enable */
+#define		AT91_US_RTSDIS		(1 << 19)		/* Request To Send Disable */
+
+#define AT91_US_MR		0x04			/* Mode Register */
+#define		AT91_US_USMODE		(0xf <<  0)		/* Mode of the USART */
+#define			AT91_US_USMODE_NORMAL		0
+#define			AT91_US_USMODE_RS485		1
+#define			AT91_US_USMODE_HWHS		2
+#define			AT91_US_USMODE_MODEM		3
+#define			AT91_US_USMODE_ISO7816_T0	4
+#define			AT91_US_USMODE_ISO7816_T1	6
+#define			AT91_US_USMODE_IRDA		8
+#define		AT91_US_USCLKS		(3   <<  4)		/* Clock Selection */
+#define			AT91_US_USCLKS_MCK		(0 <<  4)
+#define			AT91_US_USCLKS_MCK_DIV8	(1 <<  4)
+#define			AT91_US_USCLKS_SCK		(3 <<  4)
+#define		AT91_US_CHRL		(3   <<  6)		/* Character Length */
+#define			AT91_US_CHRL_5			(0 <<  6)
+#define			AT91_US_CHRL_6			(1 <<  6)
+#define			AT91_US_CHRL_7			(2 <<  6)
+#define			AT91_US_CHRL_8			(3 <<  6)
+#define		AT91_US_SYNC		(1 <<  8)		/* Synchronous Mode Select */
+#define		AT91_US_PAR		(7 <<  9)		/* Parity Type */
+#define			AT91_US_PAR_EVEN		(0 <<  9)
+#define			AT91_US_PAR_ODD		(1 <<  9)
+#define			AT91_US_PAR_SPACE		(2 <<  9)
+#define			AT91_US_PAR_MARK		(3 <<  9)
+#define			AT91_US_PAR_NONE		(4 <<  9)
+#define			AT91_US_PAR_MULTI_DROP		(6 <<  9)
+#define		AT91_US_NBSTOP		(3 << 12)		/* Number of Stop Bits */
+#define			AT91_US_NBSTOP_1		(0 << 12)
+#define			AT91_US_NBSTOP_1_5		(1 << 12)
+#define			AT91_US_NBSTOP_2		(2 << 12)
+#define		AT91_US_CHMODE		(3 << 14)		/* Channel Mode */
+#define			AT91_US_CHMODE_NORMAL		(0 << 14)
+#define			AT91_US_CHMODE_ECHO		(1 << 14)
+#define			AT91_US_CHMODE_LOC_LOOP	(2 << 14)
+#define			AT91_US_CHMODE_REM_LOOP	(3 << 14)
+#define		AT91_US_MSBF		(1 << 16)		/* Bit Order */
+#define		AT91_US_MODE9		(1 << 17)		/* 9-bit Character Length */
+#define		AT91_US_CLKO		(1 << 18)		/* Clock Output Select */
+#define		AT91_US_OVER		(1 << 19)		/* Oversampling Mode */
+#define		AT91_US_INACK		(1 << 20)		/* Inhibit Non Acknowledge */
+#define		AT91_US_DSNACK		(1 << 21)		/* Disable Successive NACK */
+#define		AT91_US_MAX_ITER	(7 << 24)		/* Max Iterations */
+#define		AT91_US_FILTER		(1 << 28)		/* Infrared Receive Line Filter */
+
+#define AT91_US_IER		0x08			/* Interrupt Enable Register */
+#define		AT91_US_RXRDY		(1 <<  0)		/* Receiver Ready */
+#define		AT91_US_TXRDY		(1 <<  1)		/* Transmitter Ready */
+#define		AT91_US_RXBRK		(1 <<  2)		/* Break Received / End of Break */
+#define		AT91_US_ENDRX		(1 <<  3)		/* End of Receiver Transfer */
+#define		AT91_US_ENDTX		(1 <<  4)		/* End of Transmitter Transfer */
+#define		AT91_US_OVRE		(1 <<  5)		/* Overrun Error */
+#define		AT91_US_FRAME		(1 <<  6)		/* Framing Error */
+#define		AT91_US_PARE		(1 <<  7)		/* Parity Error */
+#define		AT91_US_TIMEOUT	(1 <<  8)		/* Receiver Time-out */
+#define		AT91_US_TXEMPTY	(1 <<  9)		/* Transmitter Empty */
+#define		AT91_US_ITERATION	(1 << 10)		/* Max number of Repetitions Reached */
+#define		AT91_US_TXBUFE		(1 << 11)		/* Transmission Buffer Empty */
+#define		AT91_US_RXBUFF		(1 << 12)		/* Reception Buffer Full */
+#define		AT91_US_NACK		(1 << 13)		/* Non Acknowledge */
+#define		AT91_US_RIIC		(1 << 16)		/* Ring Indicator Input Change [AT91RM9200 only] */
+#define		AT91_US_DSRIC		(1 << 17)		/* Data Set Ready Input Change [AT91RM9200 only] */
+#define		AT91_US_DCDIC		(1 << 18)		/* Data Carrier Detect Input Change [AT91RM9200 only] */
+#define		AT91_US_CTSIC		(1 << 19)		/* Clear to Send Input Change */
+#define		AT91_US_RI		(1 << 20)		/* RI */
+#define		AT91_US_DSR		(1 << 21)		/* DSR */
+#define		AT91_US_DCD		(1 << 22)		/* DCD */
+#define		AT91_US_CTS		(1 << 23)		/* CTS */
+
+#define AT91_US_IDR		0x0c			/* Interrupt Disable Register */
+#define AT91_US_IMR		0x10			/* Interrupt Mask Register */
+#define AT91_US_CSR		0x14			/* Channel Status Register */
+#define AT91_US_RHR		0x18			/* Receiver Holding Register */
+#define AT91_US_THR		0x1c			/* Transmitter Holding Register */
+#define		AT91_US_SYNH		(1 << 15)		/* Transmit/Receive Sync [AT91SAM9261 only] */
+
+#define AT91_US_BRGR		0x20			/* Baud Rate Generator Register */
+#define		AT91_US_CD		(0xffff << 0)		/* Clock Divider */
+
+#define AT91_US_RTOR		0x24			/* Receiver Time-out Register */
+#define		AT91_US_TO		(0xffff << 0)		/* Time-out Value */
+
+#define AT91_US_TTGR		0x28			/* Transmitter Timeguard Register */
+#define		AT91_US_TG		(0xff << 0)		/* Timeguard Value */
+
+#define AT91_US_FIDI		0x40			/* FI DI Ratio Register */
+#define AT91_US_NER		0x44			/* Number of Errors Register */
+#define AT91_US_IF		0x4c			/* IrDA Filter Register */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 46 - 0
libcpu/arm/at91sam926x/at91_shdwc.h

@@ -0,0 +1,46 @@
+/*
+ * File      : at91_shdwc.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_SHDWC_H
+#define AT91_SHDWC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_SHDW_CR		(AT91_SHDWC + 0x00)	/* Shut Down Control Register */
+#define		AT91_SHDW_SHDW		(1    << 0)		/* Shut Down command */
+#define		AT91_SHDW_KEY		(0xa5 << 24)		/* KEY Password */
+
+#define AT91_SHDW_MR		(AT91_SHDWC + 0x04)	/* Shut Down Mode Register */
+#define		AT91_SHDW_WKMODE0	(3 << 0)		/* Wake-up 0 Mode Selection */
+#define			AT91_SHDW_WKMODE0_NONE		0
+#define			AT91_SHDW_WKMODE0_HIGH		1
+#define			AT91_SHDW_WKMODE0_LOW		2
+#define			AT91_SHDW_WKMODE0_ANYLEVEL	3
+#define		AT91_SHDW_CPTWK0	(0xf << 4)		/* Counter On Wake Up 0 */
+#define			AT91_SHDW_CPTWK0_(x)	((x) << 4)
+#define		AT91_SHDW_RTTWKEN	(1   << 16)		/* Real Time Timer Wake-up Enable */
+
+#define AT91_SHDW_SR		(AT91_SHDWC + 0x08)	/* Shut Down Status Register */
+#define		AT91_SHDW_WAKEUP0	(1 <<  0)		/* Wake-up 0 Status */
+#define		AT91_SHDW_RTTWK		(1 << 16)		/* Real-time Timer Wake-up */
+#define		AT91_SHDW_RTCWK		(1 << 17)		/* Real-time Clock Wake-up [SAM9RL] */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 154 - 0
libcpu/arm/at91sam926x/at91_tc.h

@@ -0,0 +1,154 @@
+/*
+ * File      : at91_tc.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91_TC_H
+#define AT91_TC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_TC_BCR		0xc0		/* TC Block Control Register */
+#define		AT91_TC_SYNC		(1 << 0)	/* Synchro Command */
+
+#define AT91_TC_BMR		0xc4		/* TC Block Mode Register */
+#define		AT91_TC_TC0XC0S		(3 << 0)	/* External Clock Signal 0 Selection */
+#define			AT91_TC_TC0XC0S_TCLK0		(0 << 0)
+#define			AT91_TC_TC0XC0S_NONE		(1 << 0)
+#define			AT91_TC_TC0XC0S_TIOA1		(2 << 0)
+#define			AT91_TC_TC0XC0S_TIOA2		(3 << 0)
+#define		AT91_TC_TC1XC1S		(3 << 2)	/* External Clock Signal 1 Selection */
+#define			AT91_TC_TC1XC1S_TCLK1		(0 << 2)
+#define			AT91_TC_TC1XC1S_NONE		(1 << 2)
+#define			AT91_TC_TC1XC1S_TIOA0		(2 << 2)
+#define			AT91_TC_TC1XC1S_TIOA2		(3 << 2)
+#define		AT91_TC_TC2XC2S		(3 << 4)	/* External Clock Signal 2 Selection */
+#define			AT91_TC_TC2XC2S_TCLK2		(0 << 4)
+#define			AT91_TC_TC2XC2S_NONE		(1 << 4)
+#define			AT91_TC_TC2XC2S_TIOA0		(2 << 4)
+#define			AT91_TC_TC2XC2S_TIOA1		(3 << 4)
+
+
+#define AT91_TC_CCR		0x00		/* Channel Control Register */
+#define		AT91_TC_CLKEN		(1 << 0)	/* Counter Clock Enable Command */
+#define		AT91_TC_CLKDIS		(1 << 1)	/* Counter CLock Disable Command */
+#define		AT91_TC_SWTRG		(1 << 2)	/* Software Trigger Command */
+
+#define AT91_TC_CMR		0x04		/* Channel Mode Register */
+#define		AT91_TC_TCCLKS		(7 << 0)	/* Capture/Waveform Mode: Clock Selection */
+#define			AT91_TC_TIMER_CLOCK1		(0 << 0)
+#define			AT91_TC_TIMER_CLOCK2		(1 << 0)
+#define			AT91_TC_TIMER_CLOCK3		(2 << 0)
+#define			AT91_TC_TIMER_CLOCK4		(3 << 0)
+#define			AT91_TC_TIMER_CLOCK5		(4 << 0)
+#define			AT91_TC_XC0			(5 << 0)
+#define			AT91_TC_XC1			(6 << 0)
+#define			AT91_TC_XC2			(7 << 0)
+#define		AT91_TC_CLKI		(1 << 3)	/* Capture/Waveform Mode: Clock Invert */
+#define		AT91_TC_BURST		(3 << 4)	/* Capture/Waveform Mode: Burst Signal Selection */
+#define		AT91_TC_LDBSTOP		(1 << 6)	/* Capture Mode: Counter Clock Stopped with TB Loading */
+#define		AT91_TC_LDBDIS		(1 << 7)	/* Capture Mode: Counter Clock Disable with RB Loading */
+#define		AT91_TC_ETRGEDG		(3 << 8)	/* Capture Mode: External Trigger Edge Selection */
+#define		AT91_TC_ABETRG		(1 << 10)	/* Capture Mode: TIOA or TIOB External Trigger Selection */
+#define		AT91_TC_CPCTRG		(1 << 14)	/* Capture Mode: RC Compare Trigger Enable */
+#define		AT91_TC_WAVE		(1 << 15)	/* Capture/Waveform mode */
+#define		AT91_TC_LDRA		(3 << 16)	/* Capture Mode: RA Loading Selection */
+#define		AT91_TC_LDRB		(3 << 18)	/* Capture Mode: RB Loading Selection */
+
+#define		AT91_TC_CPCSTOP		(1 <<  6)	/* Waveform Mode: Counter Clock Stopped with RC Compare */
+#define		AT91_TC_CPCDIS		(1 <<  7)	/* Waveform Mode: Counter Clock Disable with RC Compare */
+#define		AT91_TC_EEVTEDG		(3 <<  8)	/* Waveform Mode: External Event Edge Selection */
+#define			AT91_TC_EEVTEDG_NONE		(0 << 8)
+#define			AT91_TC_EEVTEDG_RISING		(1 << 8)
+#define			AT91_TC_EEVTEDG_FALLING		(2 << 8)
+#define			AT91_TC_EEVTEDG_BOTH		(3 << 8)
+#define		AT91_TC_EEVT		(3 << 10)	/* Waveform Mode: External Event Selection */
+#define			AT91_TC_EEVT_TIOB		(0 << 10)
+#define			AT91_TC_EEVT_XC0		(1 << 10)
+#define			AT91_TC_EEVT_XC1		(2 << 10)
+#define			AT91_TC_EEVT_XC2		(3 << 10)
+#define		AT91_TC_ENETRG		(1 << 12)	/* Waveform Mode: External Event Trigger Enable */
+#define		AT91_TC_WAVESEL		(3 << 13)	/* Waveform Mode: Waveform Selection */
+#define			AT91_TC_WAVESEL_UP		(0 << 13)
+#define			AT91_TC_WAVESEL_UP_AUTO		(2 << 13)
+#define			AT91_TC_WAVESEL_UPDOWN		(1 << 13)
+#define			AT91_TC_WAVESEL_UPDOWN_AUTO	(3 << 13)
+#define		AT91_TC_ACPA		(3 << 16)	/* Waveform Mode: RA Compare Effect on TIOA */
+#define			AT91_TC_ACPA_NONE		(0 << 16)
+#define			AT91_TC_ACPA_SET		(1 << 16)
+#define			AT91_TC_ACPA_CLEAR		(2 << 16)
+#define			AT91_TC_ACPA_TOGGLE		(3 << 16)
+#define		AT91_TC_ACPC		(3 << 18)	/* Waveform Mode: RC Compre Effect on TIOA */
+#define			AT91_TC_ACPC_NONE		(0 << 18)
+#define			AT91_TC_ACPC_SET		(1 << 18)
+#define			AT91_TC_ACPC_CLEAR		(2 << 18)
+#define			AT91_TC_ACPC_TOGGLE		(3 << 18)
+#define		AT91_TC_AEEVT		(3 << 20)	/* Waveform Mode: External Event Effect on TIOA */
+#define			AT91_TC_AEEVT_NONE		(0 << 20)
+#define			AT91_TC_AEEVT_SET		(1 << 20)
+#define			AT91_TC_AEEVT_CLEAR		(2 << 20)
+#define			AT91_TC_AEEVT_TOGGLE		(3 << 20)
+#define		AT91_TC_ASWTRG		(3 << 22)	/* Waveform Mode: Software Trigger Effect on TIOA */
+#define			AT91_TC_ASWTRG_NONE		(0 << 22)
+#define			AT91_TC_ASWTRG_SET		(1 << 22)
+#define			AT91_TC_ASWTRG_CLEAR		(2 << 22)
+#define			AT91_TC_ASWTRG_TOGGLE		(3 << 22)
+#define		AT91_TC_BCPB		(3 << 24)	/* Waveform Mode: RB Compare Effect on TIOB */
+#define			AT91_TC_BCPB_NONE		(0 << 24)
+#define			AT91_TC_BCPB_SET		(1 << 24)
+#define			AT91_TC_BCPB_CLEAR		(2 << 24)
+#define			AT91_TC_BCPB_TOGGLE		(3 << 24)
+#define		AT91_TC_BCPC		(3 << 26)	/* Waveform Mode: RC Compare Effect on TIOB */
+#define			AT91_TC_BCPC_NONE		(0 << 26)
+#define			AT91_TC_BCPC_SET		(1 << 26)
+#define			AT91_TC_BCPC_CLEAR		(2 << 26)
+#define			AT91_TC_BCPC_TOGGLE		(3 << 26)
+#define		AT91_TC_BEEVT		(3 << 28)	/* Waveform Mode: External Event Effect on TIOB */
+#define			AT91_TC_BEEVT_NONE		(0 << 28)
+#define			AT91_TC_BEEVT_SET		(1 << 28)
+#define			AT91_TC_BEEVT_CLEAR		(2 << 28)
+#define			AT91_TC_BEEVT_TOGGLE		(3 << 28)
+#define		AT91_TC_BSWTRG		(3 << 30)	/* Waveform Mode: Software Trigger Effect on TIOB */
+#define			AT91_TC_BSWTRG_NONE		(0 << 30)
+#define			AT91_TC_BSWTRG_SET		(1 << 30)
+#define			AT91_TC_BSWTRG_CLEAR		(2 << 30)
+#define			AT91_TC_BSWTRG_TOGGLE		(3 << 30)
+
+#define AT91_TC_CV		0x10		/* Counter Value */
+#define AT91_TC_RA		0x14		/* Register A */
+#define AT91_TC_RB		0x18		/* Register B */
+#define AT91_TC_RC		0x1c		/* Register C */
+
+#define AT91_TC_SR		0x20		/* Status Register */
+#define		AT91_TC_COVFS		(1 <<  0)	/* Counter Overflow Status */
+#define		AT91_TC_LOVRS		(1 <<  1)	/* Load Overrun Status */
+#define		AT91_TC_CPAS		(1 <<  2)	/* RA Compare Status */
+#define		AT91_TC_CPBS		(1 <<  3)	/* RB Compare Status */
+#define		AT91_TC_CPCS		(1 <<  4)	/* RC Compare Status */
+#define		AT91_TC_LDRAS		(1 <<  5)	/* RA Loading Status */
+#define		AT91_TC_LDRBS		(1 <<  6)	/* RB Loading Status */
+#define		AT91_TC_ETRGS		(1 <<  7)	/* External Trigger Status */
+#define		AT91_TC_CLKSTA		(1 << 16)	/* Clock Enabling Status */
+#define		AT91_TC_MTIOA		(1 << 17)	/* TIOA Mirror */
+#define		AT91_TC_MTIOB		(1 << 18)	/* TIOB Mirror */
+
+#define AT91_TC_IER		0x24		/* Interrupt Enable Register */
+#define AT91_TC_IDR		0x28		/* Interrupt Disable Register */
+#define AT91_TC_IMR		0x2c		/* Interrupt Mask Register */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 89 - 0
libcpu/arm/at91sam926x/at91sam9260_matrix.h

@@ -0,0 +1,89 @@
+/*
+ * File      : at91sam9260_matrix.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91SAM9260_MATRIX_H
+#define AT91SAM9260_MATRIX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
+#define		AT91_MATRIX_ULBT		(7 << 0)	/* Undefined Length Burst Type */
+#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
+#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
+#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
+#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
+#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
+
+#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
+#define		AT91_MATRIX_SLOT_CYCLE		(0xff <<  0)	/* Maximum Number of Allowed Cycles for a Burst */
+#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
+#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
+#define		AT91_MATRIX_FIXED_DEFMSTR	(7    << 18)	/* Fixed Index of Default Master */
+#define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
+#define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
+#define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
+
+#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
+#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
+#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
+#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
+#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
+#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
+#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
+
+#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+
+#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x11C)	/* EBI Chip Select Assignment Register */
+#define		AT91_MATRIX_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
+#define			AT91_MATRIX_CS4A_SMC		(0 << 4)
+#define			AT91_MATRIX_CS4A_SMC_CF1	(1 << 4)
+#define		AT91_MATRIX_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
+#define			AT91_MATRIX_CS5A_SMC		(0 << 5)
+#define			AT91_MATRIX_CS5A_SMC_CF2	(1 << 5)
+#define		AT91_MATRIX_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define		AT91_MATRIX_VDDIOMSEL		(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_VDDIOMSEL_1_8V	(0 << 16)
+#define			AT91_MATRIX_VDDIOMSEL_3_3V	(1 << 16)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 209 - 0
libcpu/arm/at91sam926x/at91sam926x.h

@@ -0,0 +1,209 @@
+/*
+ * File      : at91sam926x.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef AT91SAM9260_H
+#define AT91SAM9260_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtthread.h>
+#include "at91_aic.h"
+#include "at91_pit.h"
+#include "at91_pmc.h"
+#include "at91_rstc.h"
+#include "at91_shdwc.h"
+#include "at91sam9260_matrix.h"
+#include "at91_pio.h"
+#include "at91_serial.h"
+#include "at91_tc.h"
+#include "io.h"
+#include "irq.h"
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Peripherals */
+#define AT91SAM9260_ID_PIOA	2	/* Parallel IO Controller A */
+#define AT91SAM9260_ID_PIOB	3	/* Parallel IO Controller B */
+#define AT91SAM9260_ID_PIOC	4	/* Parallel IO Controller C */
+#define AT91SAM9260_ID_ADC	5	/* Analog-to-Digital Converter */
+#define AT91SAM9260_ID_US0	6	/* USART 0 */
+#define AT91SAM9260_ID_US1	7	/* USART 1 */
+#define AT91SAM9260_ID_US2	8	/* USART 2 */
+#define AT91SAM9260_ID_MCI	9	/* Multimedia Card Interface */
+#define AT91SAM9260_ID_UDP	10	/* USB Device Port */
+#define AT91SAM9260_ID_TWI	11	/* Two-Wire Interface */
+#define AT91SAM9260_ID_SPI0	12	/* Serial Peripheral Interface 0 */
+#define AT91SAM9260_ID_SPI1	13	/* Serial Peripheral Interface 1 */
+#define AT91SAM9260_ID_SSC	14	/* Serial Synchronous Controller */
+#define AT91SAM9260_ID_TC0	17	/* Timer Counter 0 */
+#define AT91SAM9260_ID_TC1	18	/* Timer Counter 1 */
+#define AT91SAM9260_ID_TC2	19	/* Timer Counter 2 */
+#define AT91SAM9260_ID_UHP	20	/* USB Host port */
+#define AT91SAM9260_ID_EMAC	21	/* Ethernet */
+#define AT91SAM9260_ID_ISI	22	/* Image Sensor Interface */
+#define AT91SAM9260_ID_US3	23	/* USART 3 */
+#define AT91SAM9260_ID_US4	24	/* USART 4 */
+#define AT91SAM9260_ID_US5	25	/* USART 5 */
+#define AT91SAM9260_ID_TC3	26	/* Timer Counter 3 */
+#define AT91SAM9260_ID_TC4	27	/* Timer Counter 4 */
+#define AT91SAM9260_ID_TC5	28	/* Timer Counter 5 */
+#define AT91SAM9260_ID_IRQ0	29	/* Advanced Interrupt Controller (IRQ0) */
+#define AT91SAM9260_ID_IRQ1	30	/* Advanced Interrupt Controller (IRQ1) */
+#define AT91SAM9260_ID_IRQ2	31	/* Advanced Interrupt Controller (IRQ2) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9260_BASE_TCB0		0xfffa0000
+#define AT91SAM9260_BASE_TC0		0xfffa0000
+#define AT91SAM9260_BASE_TC1		0xfffa0040
+#define AT91SAM9260_BASE_TC2		0xfffa0080
+#define AT91SAM9260_BASE_UDP		0xfffa4000
+#define AT91SAM9260_BASE_MCI		0xfffa8000
+#define AT91SAM9260_BASE_TWI		0xfffac000
+#define AT91SAM9260_BASE_US0		0xfffb0000
+#define AT91SAM9260_BASE_US1		0xfffb4000
+#define AT91SAM9260_BASE_US2		0xfffb8000
+#define AT91SAM9260_BASE_SSC		0xfffbc000
+#define AT91SAM9260_BASE_ISI		0xfffc0000
+#define AT91SAM9260_BASE_EMAC		0xfffc4000
+#define AT91SAM9260_BASE_SPI0		0xfffc8000
+#define AT91SAM9260_BASE_SPI1		0xfffcc000
+#define AT91SAM9260_BASE_US3		0xfffd0000
+#define AT91SAM9260_BASE_US4		0xfffd4000
+#define AT91SAM9260_BASE_US5		0xfffd8000
+#define AT91SAM9260_BASE_TCB1		0xfffdc000
+#define AT91SAM9260_BASE_TC3		0xfffdc000
+#define AT91SAM9260_BASE_TC4		0xfffdc040
+#define AT91SAM9260_BASE_TC5		0xfffdc080
+#define AT91SAM9260_BASE_ADC		0xfffe0000
+#define AT91_BASE_SYS			0xffffe800
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC	(0xffffe800 - AT91_BASE_SYS)
+#define AT91_SDRAMC	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC	(0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
+#define AT91_CCFG	(0xffffef10 - AT91_BASE_SYS)
+#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT	(0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR	(0xfffffd50 - AT91_BASE_SYS)
+
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9260_ROM_BASE	0x00100000	/* Internal ROM base address */
+#define AT91SAM9260_ROM_SIZE	SZ_32K		/* Internal ROM size (32Kb) */
+
+#define AT91SAM9260_SRAM0_BASE	0x00200000	/* Internal SRAM 0 base address */
+#define AT91SAM9260_SRAM0_SIZE	SZ_4K		/* Internal SRAM 0 size (4Kb) */
+#define AT91SAM9260_SRAM1_BASE	0x00300000	/* Internal SRAM 1 base address */
+#define AT91SAM9260_SRAM1_SIZE	SZ_4K		/* Internal SRAM 1 size (4Kb) */
+
+#define AT91SAM9260_UHP_BASE	0x00500000	/* USB Host controller */
+
+#define AT91SAM9XE_FLASH_BASE	0x00200000	/* Internal FLASH base address */
+#define AT91SAM9XE_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+
+#define AT91SAM9G20_ROM_BASE	0x00100000	/* Internal ROM base address */
+#define AT91SAM9G20_ROM_SIZE	SZ_32K		/* Internal ROM size (32Kb) */
+
+#define AT91SAM9G20_SRAM0_BASE	0x00200000	/* Internal SRAM 0 base address */
+#define AT91SAM9G20_SRAM0_SIZE	SZ_16K		/* Internal SRAM 0 size (16Kb) */
+#define AT91SAM9G20_SRAM1_BASE	0x00300000	/* Internal SRAM 1 base address */
+#define AT91SAM9G20_SRAM1_SIZE	SZ_16K		/* Internal SRAM 1 size (16Kb) */
+
+#define AT91SAM9G20_UHP_BASE	0x00500000	/* USB Host controller */
+
+
+
+/* Serial ports */
+#define ATMEL_MAX_UART		7		/* 6 USART3's and one DBGU port (SAM9260) */
+
+/* External Memory Map */
+#define AT91_CHIPSELECT_0	0x10000000
+#define AT91_CHIPSELECT_1	0x20000000
+#define AT91_CHIPSELECT_2	0x30000000
+#define AT91_CHIPSELECT_3	0x40000000
+#define AT91_CHIPSELECT_4	0x50000000
+#define AT91_CHIPSELECT_5	0x60000000
+#define AT91_CHIPSELECT_6	0x70000000
+#define AT91_CHIPSELECT_7	0x80000000
+
+/* SDRAM */
+#define AT91_SDRAM_BASE		AT91_CHIPSELECT_1
+
+/* Clocks */
+#define AT91_SLOW_CLOCK		32768		/* slow clock */
+
+
+/*****************************/
+/* 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
+
+struct rt_hw_register
+{
+	rt_uint32_t r0;
+	rt_uint32_t r1;
+	rt_uint32_t r2;
+	rt_uint32_t r3;
+	rt_uint32_t r4;
+	rt_uint32_t r5;
+	rt_uint32_t r6;
+	rt_uint32_t r7;
+	rt_uint32_t r8;
+	rt_uint32_t r9;
+	rt_uint32_t r10;
+	rt_uint32_t fp;
+	rt_uint32_t ip;
+	rt_uint32_t sp;
+	rt_uint32_t lr;
+	rt_uint32_t pc;
+	rt_uint32_t cpsr;
+	rt_uint32_t ORIG_r0;
+};
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 100 - 0
libcpu/arm/at91sam926x/context_gcc.S

@@ -0,0 +1,100 @@
+/*
+ * 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
+ * 2011-01-13     weety    copy from mini2440
+ */
+
+/*!
+ * \addtogroup AT91SAM926X
+ */
+/*@{*/
+
+#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

+ 193 - 0
libcpu/arm/at91sam926x/cpu.c

@@ -0,0 +1,193 @@
+/*
+ * 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
+ * 2011-01-13     weety      modified from mini2440
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "at91sam926x.h"
+
+/**
+ * @addtogroup AT91SAM926X
+ */
+/*@{*/
+
+#define ICACHE_MASK	(rt_uint32_t)(1 << 12)
+#define DCACHE_MASK	(rt_uint32_t)(1 << 2)
+
+#ifdef __GNUC__
+rt_inline rt_uint32_t cp15_rd(void)
+{
+	rt_uint32_t i;
+
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+	return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+	__asm__ __volatile__(			\
+		"mrc  p15,0,r0,c1,c0,0\n\t"	\
+		"orr  r0,r0,%0\n\t"			\
+	   	"mcr  p15,0,r0,c1,c0,0"		\
+		:							\
+		:"r" (bit)					\
+		:"memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+	__asm__ __volatile__(			\
+		"mrc  p15,0,r0,c1,c0,0\n\t"	\
+		"bic  r0,r0,%0\n\t"			\
+		"mcr  p15,0,r0,c1,c0,0"		\
+		:							\
+		:"r" (bit)					\
+		:"memory");
+}
+#endif
+
+#ifdef __CC_ARM
+rt_inline rt_uint32_t cp15_rd(void)
+{
+	rt_uint32_t i;
+
+	__asm
+	{
+		mrc p15, 0, i, c1, c0, 0
+	}
+
+	return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+	rt_uint32_t value;
+
+	__asm
+	{
+		mrc p15, 0, value, c1, c0, 0
+		orr value, value, bit
+		mcr p15, 0, value, c1, c0, 0
+	}
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+	rt_uint32_t value;
+
+	__asm
+	{
+		mrc p15, 0, value, c1, c0, 0
+		bic value, value, bit
+		mcr p15, 0, value, c1, c0, 0
+	}
+}
+#endif
+
+/**
+ * enable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+	cache_enable(ICACHE_MASK);
+}
+
+/**
+ * disable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+	cache_disable(ICACHE_MASK);
+}
+
+/**
+ * return the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+	return (cp15_rd() & ICACHE_MASK);
+}
+
+/**
+ * enable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+	cache_enable(DCACHE_MASK);
+}
+
+/**
+ * disable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+	cache_disable(DCACHE_MASK);
+}
+
+/**
+ * return the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+	return (cp15_rd() & DCACHE_MASK);
+}
+
+static void at91sam9260_reset(void)
+{
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+static void at91sam9260_poweroff(void)
+{
+	at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+	
+	rt_kprintf("Restarting system...\n");
+	at91sam9260_reset();
+
+	while(1);	/* loop forever and wait for reset to happen */
+
+	/* NEVER REACHED */
+}
+
+/**
+ *  shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_uint32_t level;
+	rt_kprintf("shutdown...\n");
+
+	level = rt_hw_interrupt_disable();
+	at91sam9260_poweroff();
+	while (level)
+	{
+		RT_ASSERT(0);
+	}
+}
+
+/*@}*/

+ 219 - 0
libcpu/arm/at91sam926x/interrupt.c

@@ -0,0 +1,219 @@
+/*
+ * File      : interrupt.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
+ * 2011-01-13     weety      first version
+ */
+
+#include <rtthread.h>
+#include "at91sam926x.h"
+
+#define MAX_HANDLERS	32
+
+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;
+
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+rt_uint32_t at91_extern_irq;
+
+#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = {
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	0,	/* Analog-to-Digital Converter */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	0,	/* Multimedia Card Interface */
+	2,	/* USB Device Port */
+	6,	/* Two-Wire Interface */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	5,	/* Serial Synchronous Controller */
+	0,
+	0,
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	2,	/* USB Host port */
+	3,	/* Ethernet */
+	0,	/* Image Sensor Interface */
+	5,	/* USART 3 */
+	5,	/* USART 4 */
+	5,	/* USART 5 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+};
+
+/**
+ * @addtogroup AT91SAM926X
+ */
+/*@{*/
+
+rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+	return RT_NULL;
+}
+
+/*
+ * Initialize the AIC interrupt controller.
+ */
+void at91_aic_init(rt_uint32_t *priority)
+{
+	rt_uint32_t i;
+
+	/*
+	 * The IVR is used by macro get_irqnr_and_base to read and verify.
+	 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
+	 */
+	for (i = 0; i < MAX_HANDLERS; i++) {
+		/* Put irq number in Source Vector Register: */
+		at91_sys_write(AT91_AIC_SVR(i), i);
+		/* Active Low interrupt, with the specified priority */
+		at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
+		//AT91_AIC_SRCTYPE_FALLING
+
+		/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
+		if (i < 8)
+			at91_sys_write(AT91_AIC_EOICR, 0);
+	}
+
+	/*
+	 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
+	 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
+	 */
+	at91_sys_write(AT91_AIC_SPU, MAX_HANDLERS);
+
+	/* No debugging in AIC: Debug (Protect) Control Register */
+	at91_sys_write(AT91_AIC_DCR, 0);
+
+	/* Disable and clear all interrupts initially */
+	at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF);
+	at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+}
+
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+	rt_int32_t i;
+	register rt_uint32_t idx;
+	rt_uint32_t *priority = at91sam9260_default_irq_priority;
+	
+	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
+			| (1 << AT91SAM9260_ID_IRQ2);
+
+	/* Initialize the AIC interrupt controller */
+	at91_aic_init(priority);
+
+	/* init exceptions table */
+	for(idx=0; idx < MAX_HANDLERS; idx++)
+	{
+		isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle;
+	}
+
+	/* 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 irq)
+{
+	/* Disable interrupt on AIC */
+	at91_sys_write(AT91_AIC_IDCR, 1 << irq);
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int irq)
+{
+	/* Enable interrupt on AIC */
+	at91_sys_write(AT91_AIC_IECR, 1 << irq);
+}
+
+/**
+ * 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;
+	}
+}
+
+/*@}*/
+
+
+static int at91_aic_set_type(unsigned irq, unsigned type)
+{
+	unsigned int smr, srctype;
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		srctype = AT91_AIC_SRCTYPE_HIGH;
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		srctype = AT91_AIC_SRCTYPE_RISING;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		if ((irq == AT91_ID_FIQ) || is_extern_irq(irq))		/* only supported on external interrupts */
+			srctype = AT91_AIC_SRCTYPE_LOW;
+		else
+			return -1;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		if ((irq == AT91_ID_FIQ) || is_extern_irq(irq))		/* only supported on external interrupts */
+			srctype = AT91_AIC_SRCTYPE_FALLING;
+		else
+			return -1;
+		break;
+	default:
+		return -1;
+	}
+
+	smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE;
+	at91_sys_write(AT91_AIC_SMR(irq), smr | srctype);
+	return 0;
+}

+ 47 - 0
libcpu/arm/at91sam926x/io.h

@@ -0,0 +1,47 @@
+/*
+ * File      : io.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
+ * 2011-01-13     weety      first version
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define AT91_BASE_SYS			0xffffe800
+
+#define IO_SPACE_LIMIT		0xFFFFFFFF
+
+#define readb(a)	(*(volatile unsigned char  *)(a))
+#define readw(a)	(*(volatile unsigned short *)(a))
+#define readl(a)	(*(volatile unsigned int   *)(a))
+
+#define writeb(v,a)	(*(volatile unsigned char  *)(a) = (v))
+#define writew(v,a)	(*(volatile unsigned short *)(a) = (v))
+#define writel(v,a)	(*(volatile unsigned int   *)(a) = (v))
+
+
+static inline unsigned int at91_sys_read(unsigned int reg_offset)
+{
+	void  *addr = (void  *)AT91_BASE_SYS;
+
+	return readl(addr + reg_offset);
+}
+
+static inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
+{
+	void *addr = (void *)AT91_BASE_SYS;
+
+	writel(value, addr + reg_offset);
+}
+
+
+#endif
+

+ 42 - 0
libcpu/arm/at91sam926x/irq.h

@@ -0,0 +1,42 @@
+/*
+ * File      : irq.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
+ * 2011-01-13     weety      first version
+ */
+ 
+#ifndef __IRQ_H__
+#define __IRQ_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * IRQ line status.
+ *
+ * Bits 0-7 are reserved 
+ *
+ * IRQ types
+ */
+#define IRQ_TYPE_NONE		0x00000000	/* Default, unspecified type */
+#define IRQ_TYPE_EDGE_RISING	0x00000001	/* Edge rising type */
+#define IRQ_TYPE_EDGE_FALLING	0x00000002	/* Edge falling type */
+#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH	0x00000004	/* Level high type */
+#define IRQ_TYPE_LEVEL_LOW	0x00000008	/* Level low type */
+#define IRQ_TYPE_SENSE_MASK	0x0000000f	/* Mask of the above */
+#define IRQ_TYPE_PROBE		0x00000010	/* Probing in progress */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 395 - 0
libcpu/arm/at91sam926x/mmu.c

@@ -0,0 +1,395 @@
+/*
+ * File      : mmu.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://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety       modified from mini2440
+ */
+
+#include <rtthread.h>
+#include "at91sam926x.h"
+
+#define _MMUTT_STARTADDRESS	 0x33FF0000
+
+#define DESC_SEC		(0x2|(1<<4))
+#define CB				(3<<2)  //cache_on, write_back
+#define CNB				(2<<2)  //cache_on, write_through
+#define NCB				(1<<2)  //cache_off,WR_BUF on
+#define NCNB				(0<<2)  //cache_off,WR_BUF off
+#define AP_RW			(3<<10) //supervisor=RW, user=RW
+#define AP_RO			(2<<10) //supervisor=RW, user=RO
+
+#define DOMAIN_FAULT	(0x0)
+#define DOMAIN_CHK		(0x1)
+#define DOMAIN_NOTCHK	(0x3)
+#define DOMAIN0			(0x0<<5)
+#define DOMAIN1			(0x1<<5)
+
+#define DOMAIN0_ATTR	(DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR	(DOMAIN_FAULT<<2)
+
+#define RW_CB		(AP_RW|DOMAIN0|CB|DESC_SEC)
+#define RW_CNB		(AP_RW|DOMAIN0|CNB|DESC_SEC)
+#define RW_NCNB		(AP_RW|DOMAIN0|NCNB|DESC_SEC)
+#define RW_FAULT	(AP_RW|DOMAIN1|NCNB|DESC_SEC)
+
+#ifdef __GNUC__
+void mmu_setttbase(register rt_uint32_t i)
+{
+	asm ("mcr p15, 0, %0, c2, c0, 0": :"r" (i));
+}
+
+void mmu_set_domain(register rt_uint32_t i)
+{
+	asm ("mcr p15,0, %0, c3, c0,  0": :"r" (i));
+}
+
+void mmu_enable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= 0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+	asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
+}
+
+void mmu_invalidate_tlb()
+{
+	asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
+}
+
+void mmu_invalidate_icache()
+{
+	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+}
+#endif
+
+#ifdef __CC_ARM
+void mmu_setttbase(rt_uint32_t i)
+{
+    __asm
+    {
+        mcr p15, 0, i, c2, c0, 0
+    }
+}
+
+void mmu_set_domain(rt_uint32_t i)
+{
+    __asm
+    {
+        mcr p15,0, i, c3, c0,  0
+    }
+}
+
+void mmu_enable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+    __asm
+    {
+        mcr p15, 0, index, c7, c14, 2
+    }
+}
+
+void mmu_invalidate_tlb()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+    __asm
+    {
+        mcr p15, 0, value, c8, c7, 0
+    }
+}
+
+void mmu_invalidate_icache()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm
+    {
+        mcr p15, 0, value, c7, c5, 0
+    }
+}
+#endif
+
+void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
+{
+    volatile rt_uint32_t *pTT;
+    volatile int i,nSec;
+    pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
+    nSec=(vaddrEnd>>20)-(vaddrStart>>20);
+    for(i=0;i<=nSec;i++)
+    {
+		*pTT = attr |(((paddrStart>>20)+i)<<20);
+		pTT++;
+    }
+}
+
+void rt_hw_mmu_init(void)
+{
+#if 0
+	int i,j;
+	//========================== IMPORTANT NOTE =========================
+	//The current stack and code area can't be re-mapped in this routine.
+	//If you want memory map mapped freely, your own sophiscated mmu
+	//initialization code is needed.
+	//===================================================================
+
+	mmu_disable_dcache();
+	mmu_disable_icache();
+
+	//If write-back is used,the DCache should be cleared.
+	for(i=0;i<64;i++)
+		for(j=0;j<8;j++)
+			mmu_clean_invalidated_cache_index((i<<26)|(j<<5));
+
+	mmu_invalidate_icache();
+
+	//To complete mmu_Init() fast, Icache may be turned on here.
+	mmu_enable_icache();
+
+	mmu_disable();
+	mmu_invalidate_tlb();
+
+	//mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
+	mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB);  //bank0
+	mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB);  //bank0
+	mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB);  			//bank0
+	mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB);  //bank1
+	mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
+	mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
+	//mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
+	mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_NCNB); //bank4 for  DM9000
+	mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
+	//30f00000->30100000, 31000000->30200000
+	mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB);	  //bank6-1
+	mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_CB); //bank6-2
+
+	mmu_setmtt(0x33f00000,0x34000000,0x33f00000,RW_NCNB);   //bank6-3
+	mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
+
+	mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
+	mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
+	mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR
+	mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used
+	mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR
+
+	mmu_setttbase(_MMUTT_STARTADDRESS);
+
+	/* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */
+	mmu_set_domain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
+
+	mmu_enable_alignfault();
+
+	mmu_enable();
+
+	/* ICache enable */
+	mmu_enable_icache();
+	/* DCache should be turned on after mmu is turned on. */
+	mmu_enable_dcache();
+#endif
+}
+

+ 106 - 0
libcpu/arm/at91sam926x/rt_list.h

@@ -0,0 +1,106 @@
+/*
+ * File      : rt_list.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, 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
+ * 2011-01-15     weety      copy from kservice APIs
+ */
+
+#ifndef __RT_LIST_H__
+#define __RT_LIST_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup rt_list
+ */
+/*@{*/
+
+/**
+ * @brief initialize a list
+ *
+ * @param l list to be initialized
+ */
+rt_inline void rt_list_init(rt_list_t *l)
+{
+	l->next = l->prev = l;
+}
+
+/**
+ * @brief insert a node after a list
+ *
+ * @param l list to insert it
+ * @param n new node to be inserted
+ */
+rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
+{
+	l->next->prev = n;
+	n->next = l->next;
+
+	l->next = n;
+	n->prev = l;
+}
+
+/**
+ * @brief insert a node before a list
+ *
+ * @param n new node to be inserted
+ * @param l list to insert it
+ */
+rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
+{
+	l->prev->next = n;
+	n->prev = l->prev;
+
+	l->prev = n;
+	n->next = l;
+}
+
+/**
+ * @brief remove node from list.
+ * @param n the node to remove from the list.
+ */
+rt_inline void rt_list_remove(rt_list_t *n)
+{
+	n->next->prev = n->prev;
+	n->prev->next = n->next;
+
+	n->next = n->prev = n;
+}
+
+/**
+ * @brief tests whether a list is empty
+ * @param l the list to test.
+ */
+rt_inline int rt_list_isempty(const rt_list_t *l)
+{
+	return l->next == l;
+}
+
+/**
+ * @brief get the struct for this entry
+ * @param node the entry point
+ * @param type the type of structure
+ * @param member the name of list in structure
+ */
+#define rt_list_entry(node, type, member) \
+    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 282 - 0
libcpu/arm/at91sam926x/serial.c

@@ -0,0 +1,282 @@
+/*
+ * 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
+ * 2011-01-13     weety      first version    	  	
+ */
+
+#include <rtthread.h>
+
+#include "serial.h"
+
+/**
+ * @addtogroup AT91SAM926X
+ */
+/*@{*/
+
+/* RT-Thread Device Interface */
+/**
+ * This function initializes serial
+ */
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	struct serial_device* uart = (struct serial_device*) dev->user_data;
+
+	if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
+	{
+
+		if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+		{
+			rt_memset(uart->int_rx->rx_buffer, 0, 
+				sizeof(uart->int_rx->rx_buffer));
+			uart->int_rx->read_index = uart->int_rx->save_index = 0;
+		}
+		
+		if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+		{
+			rt_memset(uart->int_tx->tx_buffer, 0, 
+				sizeof(uart->int_tx->tx_buffer));
+			uart->int_tx->write_index = uart->int_tx->save_index = 0;
+		}
+
+		dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
+	}
+
+	return RT_EOK;
+}
+
+/* save a char to serial buffer */
+static void rt_serial_savechar(struct serial_device* uart, char ch)
+{
+	rt_base_t level;
+	
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
+	uart->int_rx->save_index ++;
+	if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
+		uart->int_rx->save_index = 0;
+	
+	/* if the next position is read index, discard this 'read char' */
+	if (uart->int_rx->save_index == uart->int_rx->read_index)
+	{
+		uart->int_rx->read_index ++;
+		if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+			uart->int_rx->read_index = 0;
+	}
+
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{	
+	RT_ASSERT(dev != RT_NULL);
+	
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{	
+	RT_ASSERT(dev != RT_NULL);
+
+	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;
+	rt_err_t err_code;
+	struct serial_device* uart;
+	
+	ptr = buffer;
+	err_code = RT_EOK;
+	uart = (struct serial_device*)dev->user_data;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		rt_base_t level;
+
+		/* interrupt mode Rx */
+		while (size)
+		{
+			if (uart->int_rx->read_index != uart->int_rx->save_index)
+			{
+				*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
+				size --;
+
+				/* disable interrupt */
+				level = rt_hw_interrupt_disable();
+
+				uart->int_rx->read_index ++;
+				if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+					uart->int_rx->read_index = 0;
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+			}
+			else
+			{
+				/* set error code */
+				err_code = -RT_EEMPTY;
+				break;
+			}
+		}
+	}
+	else
+	{
+		/* polling mode */
+		while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+		{
+			while (uart->uart_device->USART_CSR & RXRDY)
+			{
+				*ptr = uart->uart_device->USART_RHR & 0xff;
+				ptr ++;
+			}
+		}
+	}
+
+	/* set error code */
+	rt_set_errno(err_code);
+	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+}
+
+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;
+	rt_err_t err_code;
+	struct serial_device* uart;
+	
+	err_code = RT_EOK;
+	ptr = (rt_uint8_t*)buffer;
+	uart = (struct serial_device*)dev->user_data;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_TX)
+	{
+		/* interrupt mode Tx */
+		while (uart->int_tx->save_index != uart->int_tx->write_index)
+		{
+			/* save on tx buffer */
+			uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
+			
+			-- size;
+
+			/* move to next position */
+			uart->int_tx->save_index ++;
+			
+			/* wrap save index */
+			if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
+				uart->int_tx->save_index = 0;
+		}
+		
+		/* set error code */
+		if (size > 0)
+			err_code = -RT_EFULL;
+	}
+	else
+	{
+		/* polling mode */
+		while (size)
+		{
+			/*
+			 * to be polite with serial console add a line feed
+			 * to the carriage return character
+			 */
+			if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
+			{
+				while (!(uart->uart_device->USART_CSR & TXRDY));
+				uart->uart_device->USART_THR = '\r';
+			}
+
+			while (!(uart->uart_device->USART_CSR & TXRDY));
+			uart->uart_device->USART_THR = (*ptr & 0xFF);
+
+			++ptr; --size;
+		}
+	}	
+
+	/* set error code */
+	rt_set_errno(err_code);
+	
+	return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	RT_ASSERT(dev != RT_NULL);
+
+	switch (cmd)
+	{
+	case RT_DEVICE_CTRL_SUSPEND:
+		/* suspend device */
+		dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
+		break;
+	
+	case RT_DEVICE_CTRL_RESUME:
+		/* resume device */
+		dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
+		break;
+	}
+	
+	return RT_EOK;
+}
+
+/*
+ * serial register
+ */
+rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
+{
+	RT_ASSERT(device != RT_NULL);
+
+	device->type 		= RT_Device_Class_Char;
+	device->rx_indicate = RT_NULL;
+	device->tx_complete = RT_NULL;
+	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;
+	device->user_data   = serial;
+
+	/* register a character device */
+	return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
+}
+	
+/* ISR for serial interrupt */
+void rt_hw_serial_isr(rt_device_t device)
+{
+	struct serial_device* uart = (struct serial_device*) device->user_data;
+	
+	/* interrupt mode receive */	
+	RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
+
+	/* save on rx buffer */
+	while (uart->uart_device->USART_CSR & RXRDY)
+	{
+		rt_serial_savechar(uart, uart->uart_device->USART_RHR & 0xff);
+	}
+
+	/* invoke callback */
+	if (device->rx_indicate != RT_NULL)
+	{
+		rt_size_t rx_length;
+		
+		/* get rx length */
+		rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
+			UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
+			uart->int_rx->save_index - uart->int_rx->read_index;
+
+		device->rx_indicate(device, rx_length);
+	}	
+}
+
+/*@}*/

+ 76 - 0
libcpu/arm/at91sam926x/serial.h

@@ -0,0 +1,76 @@
+#ifndef __RT_HW_SERIAL_H__
+#define __RT_HW_SERIAL_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "at91sam926x.h"
+
+#define RXRDY			0x01
+#define TXRDY			(1 << 1)
+#define BPS					115200	/* serial baudrate */
+
+#define UART_RX_BUFFER_SIZE		64
+#define UART_TX_BUFFER_SIZE		64
+
+struct serial_int_rx
+{
+	rt_uint8_t  rx_buffer[UART_RX_BUFFER_SIZE];
+	rt_uint32_t read_index, save_index;
+};
+
+struct serial_int_tx
+{
+	rt_uint8_t  tx_buffer[UART_TX_BUFFER_SIZE];
+	rt_uint32_t write_index, save_index;
+};
+
+typedef struct uartport
+{
+/* USART register offsets */
+	volatile rt_uint32_t USART_CR;
+	volatile rt_uint32_t USART_MR;
+	volatile rt_uint32_t USART_IER;
+	volatile rt_uint32_t USART_IDR;
+	volatile rt_uint32_t USART_IMR;
+	volatile rt_uint32_t USART_CSR;
+	volatile rt_uint32_t USART_RHR;
+	volatile rt_uint32_t USART_THR;
+	volatile rt_uint32_t USART_BRGR;
+	volatile rt_uint32_t USART_RTOR;
+	volatile rt_uint32_t USART_TTGR;
+	volatile rt_uint32_t reseverd0[5];
+	volatile rt_uint32_t USART_FIDI;
+	volatile rt_uint32_t USART_NER;
+	volatile rt_uint32_t USART_XXR;
+	volatile rt_uint32_t USART_IFR;
+	volatile rt_uint32_t reserved1[44];
+	volatile rt_uint32_t USART_RPR;
+	volatile rt_uint32_t USART_RCR;
+	volatile rt_uint32_t USART_TPR;
+	volatile rt_uint32_t USART_TCR;
+	volatile rt_uint32_t USART_RNPR;
+	volatile rt_uint32_t USART_RNCR;
+	volatile rt_uint32_t USART_TNPR;
+	volatile rt_uint32_t USART_TNCR;
+	volatile rt_uint32_t USART_PTCR;
+	volatile rt_uint32_t USART_PTSR;
+}uartport;
+
+
+struct serial_device
+{
+	uartport* uart_device;
+	
+	/* rx structure */
+	struct serial_int_rx* int_rx;
+
+	/* tx structure */
+	struct serial_int_tx* int_tx;
+};
+
+rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
+
+void rt_hw_serial_isr(rt_device_t device);
+
+#endif

+ 60 - 0
libcpu/arm/at91sam926x/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
+ * 2011-01-13     weety      copy from mini2440
+ */
+#include <rtthread.h>
+#include "at91sam926x.h"
+
+/**
+ * @addtogroup AT91SAM926X
+ */
+/*@{*/
+
+/**
+ * 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)
+{
+	rt_uint32_t *stk;
+
+	stk 	 = (rt_uint32_t*)stack_addr;
+	*(stk) 	 = (rt_uint32_t)tentry;			/* entry point */
+	*(--stk) = (rt_uint32_t)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) = (rt_uint32_t)parameter;		/* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 385 - 0
libcpu/arm/at91sam926x/start_gcc.S

@@ -0,0 +1,385 @@
+/*
+ * 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
+ * 2011-01-13     weety      first version
+ */
+
+#define CONFIG_STACKSIZE 	512
+#define S_FRAME_SIZE 		72
+
+#define S_OLD_R0 			68
+#define S_PSR  				64
+#define S_PC  				60
+#define S_LR  				56
+#define S_SP  				52
+
+#define S_IP  					48
+#define S_FP  				44
+#define S_R10  				40
+#define S_R9  				36
+#define S_R8  				32
+#define S_R7  				28
+#define S_R6  				24
+#define S_R5  				20
+#define S_R4  				16
+#define S_R3  				12
+#define S_R2  				8
+#define S_R1  				4
+#define S_R0 				0
+
+.equ 	USERMODE, 			0x10
+.equ 	FIQMODE,			0x11
+.equ 	IRQMODE,			0x12
+.equ 	SVCMODE,			0x13
+.equ 	ABORTMODE,			0x17
+.equ 	UNDEFMODE,			0x1b
+.equ 	MODEMASK,			0x1f
+.equ 	NOINT,				0xc0
+
+.equ 	RAM_BASE,			0x00000000	/*Start address of RAM		*/
+.equ 	ROM_BASE,			0x20000000	/*Start address of Flash	*/
+
+
+#define		AT91_RSTC_PROCRST	(1 << 0)		/* Processor Reset */
+#define		AT91_RSTC_PERRST	(1 << 2)
+#define		AT91_RSTC_KEY		(0xa5 << 24)
+#define AT91_MATRIX_BASE	0xffffee00
+#define AT91_MATRIX_MRCR	(AT91_MATRIX_BASE + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define		AT91_AIC_BASE	0xfffff000
+#define		AT91_AIC_IDCR	0x124	/* Interrupt Disable Command Register */
+#define		AT91_AIC_ICCR	0x128	/* Interrupt Clear Command Register */
+
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table
+ *
+ *************************************************************************
+ */
+
+.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
+
+.balignl 	16,0xdeadbeef
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+/*
+ * 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
+
+/* IRQ stack memory (calculated at run-time) 						*/
+.globl IRQ_STACK_START
+IRQ_STACK_START:
+	.word _irq_stack_start + 1024
+	
+.globl FIQ_STACK_START
+FIQ_STACK_START:
+	.word _fiq_stack_start + 1024
+	
+.globl UNDEFINED_STACK_START
+UNDEFINED_STACK_START:
+	.word _undefined_stack_start + CONFIG_STACKSIZE
+	
+.globl ABORT_STACK_START
+ABORT_STACK_START:
+	.word _abort_stack_start + CONFIG_STACKSIZE
+	
+.globl _STACK_START
+_STACK_START:
+	.word _svc_stack_start + 4096
+
+/* ----------------------------------entry------------------------------*/
+reset:
+	
+	/* set the cpu to SVC32 mode 	*/
+	mrs		r0,cpsr
+	bic		r0,r0,#MODEMASK
+	orr		r0,r0,#SVCMODE
+	msr		cpsr,r0
+
+	/* mask all IRQs by clearing all bits in the INTMRs 				*/
+	ldr	r1, =AT91_AIC_BASE
+	ldr	r0, =0xffffffff
+	str	r0, [r1, #AT91_AIC_IDCR]
+	str	r0, [r1, #AT91_AIC_ICCR]
+	
+
+	/*remap internal ram to 0x00000000 address*/
+	ldr	r0, =AT91_MATRIX_MRCR
+	ldr	r1, =(AT91_MATRIX_RCB0|AT91_MATRIX_RCB1)
+	str	r1, [r0]
+
+	/* set interrupt vector 		*/
+#if 1
+	ldr 	r0, _TEXT_BASE//_load_address
+	//ldr		r1, =0x200000				/* target address    				*/
+	mov	r1, #0x00
+	add	r2, r0, #0x40			/* size, 32bytes         			*/
+
+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
+	
+	/* setup stack */
+	bl		stack_setup
+
+	/* clear .bss */
+	mov   	r0,#0                   /* get a zero 						*/
+	ldr   	r1,=__bss_start         /* bss start 						*/
+	ldr   	r2,=__bss_end           /* bss end 							*/
+	
+bss_loop:
+	cmp   	r1,r2                   /* check if data to clear 			*/
+	strlo 	r0,[r1],#4              /* clear 4 bytes 					*/
+	blo   	bss_loop                /* loop until done 					*/
+
+	/* call C++ constructors of global objects 							*/
+	ldr 	r0, =__ctors_start__
+	ldr 	r1, =__ctors_end__
+	
+ctor_loop:
+	cmp 	r0, r1
+	beq 	ctor_end
+	ldr 	r2, [r0], #4
+	stmfd 	sp!, {r0-r1}
+	mov 	lr, pc
+	bx 		r2
+	ldmfd 	sp!, {r0-r1}
+	b		ctor_loop
+	
+ctor_end:
+
+	/* start RT-Thread Kernel 		*/
+	ldr		pc, _rtthread_startup
+
+_rtthread_startup: 
+	.word rtthread_startup
+#if defined (__FLASH_BUILD__)
+_load_address: 
+	.word ROM_BASE + _TEXT_BASE
+#else
+_load_address: 
+	.word RAM_BASE + _TEXT_BASE
+#endif
+
+.global cpu_reset
+cpu_reset:
+	ldr	r0, =0xfffffd00
+	ldr	r1, =(AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST)
+	str	r1, [r0]
+	mov	pc, lr
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+/* exception handlers 				*/
+	.align  5
+vector_undef:
+	sub 	sp, sp, #S_FRAME_SIZE
+	stmia 	sp, {r0 - r12}   		/* Calling r0-r12					*/
+	add		r8, sp, #S_PC
+	stmdb   r8, {sp, lr}^           /* Calling SP, LR					*/
+	str		lr, [r8, #0]            /* Save calling PC					*/
+	mrs		r6, spsr
+	str		r6, [r8, #4]            /* Save CPSR						*/
+	str		r0, [r8, #8]            /* Save OLD_R0						*/
+	mov		r0, sp
+
+	bl		rt_hw_trap_udef
+
+	.align	5
+vector_swi:
+	bl 		rt_hw_trap_swi
+
+	.align	5
+vector_pabt:
+	bl 		rt_hw_trap_pabt
+
+	.align	5
+vector_dabt:
+	sub 	sp, sp, #S_FRAME_SIZE
+	stmia 	sp, {r0 - r12}   		/* Calling r0-r12					*/
+	add		r8, sp, #S_PC
+	stmdb   r8, {sp, lr}^           /* Calling SP, LR					*/
+	str		lr, [r8, #0]            /* Save calling PC					*/
+	mrs		r6, spsr
+	str		r6, [r8, #4]            /* Save CPSR						*/
+	str		r0, [r8, #8]            /* Save OLD_R0						*/
+	mov		r0, sp
+
+	bl 		rt_hw_trap_dabt
+
+	.align	5
+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	*/
+
+stack_setup:
+	mrs		r0, cpsr
+	bic		r0, r0, #MODEMASK
+	orr		r1, r0, #UNDEFMODE|NOINT
+	msr		cpsr_cxsf, r1			/* undef mode						*/
+	ldr		sp, UNDEFINED_STACK_START
+
+	orr		r1,r0,#ABORTMODE|NOINT
+	msr		cpsr_cxsf,r1			/* abort mode						*/
+	ldr		sp, ABORT_STACK_START
+
+	orr		r1,r0,#IRQMODE|NOINT
+	msr		cpsr_cxsf,r1			/* IRQ mode							*/
+	ldr		sp, IRQ_STACK_START
+
+	orr		r1,r0,#FIQMODE|NOINT
+	msr		cpsr_cxsf,r1			/* FIQ mode							*/
+	ldr		sp, FIQ_STACK_START
+
+	bic		r0,r0,#MODEMASK
+	orr		r1,r0,#SVCMODE|NOINT
+	msr		cpsr_cxsf,r1			/* SVC mode							*/
+
+	ldr		sp, _STACK_START
+
+	/* USER mode is not initialized. */
+	mov		pc,lr					/* The LR register may be not valid for the mode changes.*/
+
+/*/*}*/
+
+

+ 277 - 0
libcpu/arm/at91sam926x/system_clock.c

@@ -0,0 +1,277 @@
+/*
+ * File      : clock.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
+ * 2011-01-13     weety       first version
+ */
+
+#include <rtthread.h>
+#include "rt_list.h"
+#include "at91sam926x.h"
+
+static rt_list_t clocks;
+
+struct clk {
+	char name[32];
+	rt_uint32_t rate_hz;
+	struct clk *parent;
+	rt_list_t  node;
+};
+
+static struct clk clk32k = {
+	.name = "clk32k",
+	.rate_hz = AT91_SLOW_CLOCK,
+};
+
+static struct clk main_clk = {
+	.name = "main",
+};
+
+static struct clk plla = {
+	.name = "plla",
+};
+
+static struct clk mck = {
+	.name = "mck",
+};
+
+static struct clk uhpck = {
+	.name = "uhpck",
+};
+
+static struct clk pllb = {
+	.name = "pllb",
+	.parent = &main_clk,
+};
+
+static struct clk udpck = {
+	.name = "udpck",
+	.parent = &pllb,
+};
+
+static struct clk *const standard_pmc_clocks[] = {
+	/* four primary clocks */
+	&clk32k,
+	&main_clk,
+	&plla,
+
+	/* MCK */
+	&mck
+};
+
+/* clocks cannot be de-registered no refcounting necessary */
+struct clk *clk_get(const char *id)
+{
+	struct clk *clk;
+	rt_list_t *list;
+	
+	for (list = (&clocks)->next; list != &clocks; list = list->next)
+	{
+		clk = (struct clk *)rt_list_entry(list, struct clk, node);
+		if (strcmp(id, clk->name) == 0)
+			return clk;
+	}
+
+	return RT_NULL;
+}
+
+rt_uint32_t clk_get_rate(struct clk *clk)
+{
+	rt_uint32_t	flags;
+	rt_uint32_t	rate;
+
+	for (;;) {
+		rate = clk->rate_hz;
+		if (rate || !clk->parent)
+			break;
+		clk = clk->parent;
+	}
+	return rate;
+}
+
+static rt_uint32_t at91_pll_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
+{
+	unsigned mul, div;
+
+	div = reg & 0xff;
+	mul = (reg >> 16) & 0x7ff;
+	if (div && mul) {
+		freq /= div;
+		freq *= mul + 1;
+	} else
+		freq = 0;
+
+	return freq;
+}
+
+static unsigned at91_pll_calc(unsigned main_freq, unsigned out_freq)
+{
+	unsigned i, div = 0, mul = 0, diff = 1 << 30;
+	unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
+
+	/* PLL output max 240 MHz (or 180 MHz per errata) */
+	if (out_freq > 240000000)
+		goto fail;
+
+	for (i = 1; i < 256; i++) {
+		int diff1;
+		unsigned input, mul1;
+
+		/*
+		 * PLL input between 1MHz and 32MHz per spec, but lower
+		 * frequences seem necessary in some cases so allow 100K.
+		 * Warning: some newer products need 2MHz min.
+		 */
+		input = main_freq / i;
+		if (input < 100000)
+			continue;
+		if (input > 32000000)
+			continue;
+
+		mul1 = out_freq / input;
+		if (mul1 > 2048)
+			continue;
+		if (mul1 < 2)
+			goto fail;
+
+		diff1 = out_freq - input * mul1;
+		if (diff1 < 0)
+			diff1 = -diff1;
+		if (diff > diff1) {
+			diff = diff1;
+			div = i;
+			mul = mul1;
+			if (diff == 0)
+				break;
+		}
+	}
+	if (i == 256 && diff > (out_freq >> 5))
+		goto fail;
+	return ret | ((mul - 1) << 16) | div;
+fail:
+	return 0;
+}
+
+static rt_uint32_t at91_usb_rate(struct clk *pll, rt_uint32_t freq, rt_uint32_t reg)
+{
+	if (pll == &pllb && (reg & AT91_PMC_USB96M))
+		return freq / 2;
+	else
+		return freq;
+}
+
+
+/* PLLB generated USB full speed clock init */
+static void at91_pllb_usbfs_clock_init(rt_uint32_t main_clock)
+{
+	rt_uint32_t at91_pllb_usb_init;
+	/*
+	 * USB clock init:  choose 48 MHz PLLB value,
+	 * disable 48MHz clock during usb peripheral suspend.
+	 *
+	 * REVISIT:  assumes MCK doesn't derive from PLLB!
+	 */
+	uhpck.parent = &pllb;
+
+	at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
+	pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
+	
+	at91_sys_write(AT91_CKGR_PLLBR, 0);
+
+	udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+	uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+}
+
+static struct clk *at91_css_to_clk(unsigned long css)
+{
+	switch (css) {
+		case AT91_PMC_CSS_SLOW:
+			return &clk32k;
+		case AT91_PMC_CSS_MAIN:
+			return &main_clk;
+		case AT91_PMC_CSS_PLLA:
+			return &plla;
+		case AT91_PMC_CSS_PLLB:
+			return &pllb;
+	}
+
+	return RT_NULL;
+}
+
+#define false 0
+#define true  1
+int at91_clock_init(rt_uint32_t main_clock)
+{
+	unsigned tmp, freq, mckr;
+	int i;
+	int pll_overclock = false;
+
+	/*
+	 * When the bootloader initialized the main oscillator correctly,
+	 * there's no problem using the cycle counter.  But if it didn't,
+	 * or when using oscillator bypass mode, we must be told the speed
+	 * of the main clock.
+	 */
+	if (!main_clock) {
+		do {
+			tmp = at91_sys_read(AT91_CKGR_MCFR);
+		} while (!(tmp & AT91_PMC_MAINRDY));
+		main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
+	}
+	main_clk.rate_hz = main_clock;
+
+	/* report if PLLA is more than mildly overclocked */
+	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+	if (plla.rate_hz > 209000000)
+		pll_overclock = true;
+	if (pll_overclock)
+		;//rt_kprintf("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
+
+	at91_pllb_usbfs_clock_init(main_clock);
+
+	/*
+	 * MCK and CPU derive from one of those primary clocks.
+	 * For now, assume this parentage won't change.
+	 */
+	mckr = at91_sys_read(AT91_PMC_MCKR);
+	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
+	freq = mck.parent->rate_hz;
+	freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));				/* prescale */
+	
+	mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
+
+	/* Register the PMC's standard clocks */
+	rt_list_init(&clocks);
+	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
+		rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node);
+
+	rt_list_insert_after(&clocks, &pllb.node);
+	rt_list_insert_after(&clocks, &uhpck.node);
+	rt_list_insert_after(&clocks, &udpck.node);
+
+	/* MCK and CPU clock are "always on" */
+	//clk_enable(&mck);
+
+	/*rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
+		freq / 1000000, (unsigned) mck.rate_hz / 1000000,
+		(unsigned) main_clock / 1000000,
+		((unsigned) main_clock % 1000000) / 1000);*///cause blocked
+
+	return 0;
+}
+
+/**
+ * @brief System Clock Configuration
+ */
+void rt_hw_clock_init(void)
+{
+	at91_clock_init(18432000);
+}
+

+ 173 - 0
libcpu/arm/at91sam926x/trap.c

@@ -0,0 +1,173 @@
+/*
+ * 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
+ * 2011-01-13     weety      modified from mini2440
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "at91sam926x.h"
+
+/**
+ * @addtogroup AT91SAM926X
+ */
+/*@{*/
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+/**
+ * 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_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	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_hw_show_register(regs);
+
+	rt_kprintf("software interrupt\n");
+	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_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	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_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	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;
+	rt_uint32_t irqstat, irq, mask;
+	//rt_kprintf("irq interrupt request\n");
+	/* get irq number */
+	irq = at91_sys_read(AT91_AIC_IVR);
+	/* clear pending register */
+	irqstat = at91_sys_read(AT91_AIC_ISR);
+	if (irqstat == 0)
+	{
+		rt_kprintf("No interrupt occur\n");
+		at91_sys_write(AT91_AIC_EOICR, 0);
+		return;
+	}
+	//at91_sys_write(AT91_AIC_EOICR, 0x55555555);
+	
+	/* get interrupt service routine */
+	isr_func = isr_table[irq];
+
+	/* turn to interrupt service routine */
+	isr_func(irq);
+	at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt
+}
+
+void rt_hw_trap_fiq()
+{
+	rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/