Selaa lähdekoodia

porting for microblaze. nl1031

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1843 bbd45198-f89e-11dd-88c7-29a3b14d5316
nongli1031@gmail.com 13 vuotta sitten
vanhempi
commit
08f25161d9

+ 26 - 0
bsp/microblaze/application.c

@@ -0,0 +1,26 @@
+/*
+ * File      : app.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
+ * 2006-06-05     Bernard      the first version
+ */
+
+/**
+ * @addtogroup sam7s
+ */
+/*@{*/
+#include <rtthread.h>
+
+int rt_application_init()
+{
+	return 0;
+}
+
+/*@}*/

+ 232 - 0
bsp/microblaze/board.c

@@ -0,0 +1,232 @@
+/*
+ * File      : board.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first implementation
+ *
+ * 2011-12-17     nl1031       for MacroBlaze
+ *
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "xbasic_types.h"
+#include "board.h"
+#include "xgpio.h"
+#include "xparameters.h"
+#include "xuartlite.h"
+#include "xtmrctr.h"
+#include "xintc.h"
+#include "xstatus.h"
+#include "xuartlite_l.h"
+#include "xintc_l.h"
+
+#ifdef RT_USING_UART1
+#include "serial.h"
+#endif
+
+#define  TIMER_CNTR_0		0
+#define  PIV  				(XPAR_PROC_BUS_0_FREQ_HZ / RT_TICK_PER_SECOND)
+#define  LEDS_DEVICE_ID    	XPAR_LEDS_4BITS_DEVICE_ID
+#define  RS232_DEVICE_ID   	XPAR_USB_UART_DEVICE_ID
+
+#ifdef   RT_USING_UART1
+#define  USB_UART_BASE			((struct uartport *)XPAR_USB_UART_BASEADDR)
+#endif
+
+/* Global Variables: */
+XTmrCtr 	timer; 			/* The instance of the timer */
+XGpio 		gpio_output; 	/* The driver instance for GPIO Device configured as O/P */
+XUartLite 	uart_lite; 		/* Instance of the UartLite device */
+XIntc 		int_ctl; 		/* The instance of the Interrupt Controller */
+static		rt_uint32_t led_data;
+
+
+
+static void rt_hw_board_led_init(void);
+
+/** 
+ * This function will init led on the board
+ */
+static void rt_hw_board_led_init()
+{
+	rt_uint32_t status;
+	led_data = 0;
+	status = XGpio_Initialize(&gpio_output, LEDS_DEVICE_ID);
+	if (status != XST_SUCCESS)
+	{
+		return;
+	}
+
+	/*
+	 * Set the direction for all signals to be outputs
+	 */
+	XGpio_SetDataDirection(&gpio_output, 1, 0x0);
+	/*
+	 * Set the GPIO outputs to high
+	 */
+	XGpio_DiscreteWrite(&gpio_output, 1, 3);
+}
+
+/** 
+ * This function will take the led on board on.
+ *
+ * @param n the number nth led
+ */
+void rt_hw_board_led_on(rt_uint32_t led)
+{
+	led_data |= led;
+	XGpio_DiscreteWrite(&gpio_output, 1, led_data);
+}
+
+/** 
+ * This function will take the led on board off.
+ *
+ * @param n the number nth led
+ */
+void rt_hw_board_led_off(rt_uint32_t led)
+{
+	led_data &= ~led;
+	XGpio_DiscreteWrite(&gpio_output, 1, led_data);
+}
+
+
+void rt_hw_led_flash(void)
+{
+	rt_uint32_t i;
+
+	rt_hw_board_led_off(1);
+	for (i = 0; i < 20000; i ++);
+
+	rt_hw_board_led_on(1);
+	for (i = 0; i < 20000; i ++);
+}
+
+
+#ifdef RT_USING_CONSOLE
+
+/*
+ * RT-Thread Console Interface, used by rt_kprintf
+ */
+/**
+ * This function is used to display a string on console, normally, it's
+ * invoked by rt_kprintf
+ *
+ * @param str the displayed string
+ */
+void rt_hw_console_output(const char* str)
+{
+	while (*str)
+	{
+
+		/* Transmit Character */
+		XUartLite_SendByte(STDOUT_BASEADDRESS, *str);
+		if (*str == '\n')
+			XUartLite_SendByte(STDOUT_BASEADDRESS, '\r');
+		str++;
+	}
+}
+
+static void rt_hw_console_init()
+{
+	rt_uint32_t status;
+
+	/*
+	 * Initialize the UartLite driver so that it is ready to use.
+	 */
+	status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
+	if (status != XST_SUCCESS)
+	{
+		return;
+	}
+
+}
+#endif
+
+
+void rt_hw_timer_handler(void)
+{
+	rt_uint32_t csr;
+	csr = XTmrCtr_ReadReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET);
+	/*
+	 * Check if timer expired and interrupt occured
+	 */
+	if (csr & XTC_CSR_INT_OCCURED_MASK)
+	{
+		rt_tick_increase();
+		XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, csr | XTC_CSR_INT_OCCURED_MASK);
+	}
+
+}
+
+
+/*
+*********************************************************************************************************
+*                                           rt_intc_init()
+*
+* Description: This function intializes the interrupt controller by registering the appropriate handler
+*              functions and enabling interrupts.
+*
+* Arguments  : None
+*
+* Returns    : None
+*********************************************************************************************************
+*/
+
+void  rt_intc_init (void)
+{
+    XStatus  status;
+
+    XIntc_MasterDisable(XPAR_INTC_0_BASEADDR);
+
+    status = XIntc_Initialize(&int_ctl, XPAR_INTC_0_DEVICE_ID);
+
+	/* install interrupt handler */
+    rt_hw_interrupt_install(XPAR_INTC_0_TMRCTR_0_VEC_ID, (rt_isr_handler_t)rt_hw_timer_handler, RT_NULL);
+	rt_hw_interrupt_umask(XPAR_INTC_0_TMRCTR_0_VEC_ID);
+
+	XIntc_Start(&int_ctl, XIN_REAL_MODE);
+
+}
+
+
+void  rt_tmr_init (void)
+{
+	rt_uint32_t ctl;
+    XStatus  	status;
+
+    status = XTmrCtr_Initialize(&timer,XPAR_AXI_TIMER_0_DEVICE_ID);
+	XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TLR_OFFSET, PIV);
+    ctl = XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK;
+	XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, ctl);
+}
+
+
+
+/**
+ * This function will initial SPARTAN 6 LX9 board.
+ */
+void rt_hw_board_init()
+{
+	/* init hardware console */
+	rt_hw_console_init();
+
+	/* init led */
+	rt_hw_board_led_init();
+
+	/* init intc */
+    rt_intc_init();
+
+    /* timer init */
+    rt_tmr_init();
+
+
+}

+ 22 - 0
bsp/microblaze/board.h

@@ -0,0 +1,22 @@
+/*
+ * 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://openlab.rt-thread.com/license/LICENSE
+ *
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+
+#define MCK		50000000
+
+void rt_hw_board_led_on(rt_uint32_t);
+void rt_hw_board_led_off(rt_uint32_t);
+void rt_hw_board_init(void);
+
+#endif

+ 190 - 0
bsp/microblaze/rtconfig.h

@@ -0,0 +1,190 @@
+/* RT-Thread config file */
+#ifndef __RTTHREAD_CFG_H__
+#define __RTTHREAD_CFG_H__
+
+#define IDLE_THREAD_STACK_SIZE	2048
+
+/* RT_NAME_MAX*/
+#define RT_NAME_MAX	32
+
+/* RT_ALIGN_SIZE*/
+#define RT_ALIGN_SIZE	4
+
+/* PRIORITY_MAX*/
+#define RT_THREAD_PRIORITY_MAX	32
+
+/* Tick per Second*/
+#define RT_TICK_PER_SECOND	100
+
+
+/* SECTION: RT_DEBUG */
+/* Thread Debug*/
+/* #define RT_THREAD_DEBUG */
+
+/* Using Hook*/
+#define RT_USING_HOOK
+
+/* SECTION: IPC */
+/* Using Semaphore*/
+#define RT_USING_SEMAPHORE
+
+/* Using Mutex*/
+#define RT_USING_MUTEX
+
+/* Using Event*/
+#define RT_USING_EVENT
+
+/* Using Faset Event*/
+/* #define RT_USING_FASTEVENT */
+
+/* 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
+
+/* buffer size for UART reception*/
+#define RT_UART_RX_BUFFER_SIZE	64
+
+/* buffer size for UART transmission*/
+#define RT_UART_TX_BUFFER_SIZE	64
+
+/* Using UART1*/
+#define RT_USING_UART1
+
+/* Using UART1*/
+/* #define RT_USING_UART2 */
+
+/* Using UART1*/
+/* #define RT_USING_UART3 */
+
+/* SECTION: Console options */
+#define RT_USING_CONSOLE
+/* the buffer size of console*/
+#define RT_CONSOLEBUF_SIZE	256
+
+/* SECTION: FinSH shell options */
+/* Using FinSH as Shell*/
+#define RT_USING_FINSH
+/* use symbol table */
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_STACK_SIZE 8192
+#define RT_USING_TC
+
+
+/* SECTION: a runtime libc library */
+/* a runtime libc library*/
+/* #define RT_USING_NEWLIB */
+#define RT_USING_MINILIBC
+
+/* SECTION: C++ support */
+/* Using C++ support*/
+/* #define RT_USING_CPLUSPLUS */
+
+/* SECTION: RTGUI support */
+/* using RTGUI support*/
+/* #define RT_USING_RTGUI */
+
+/* SECTION: Device filesystem support */
+/* using DFS support*/
+/* #define RT_USING_DFS */
+
+/* SECTION: EFSL filesystem support */
+/* using  EFSL filesystem  support*/
+/* #define RT_USING_EFSL */
+
+/* SECTION: lwip, a lighwight TCP/IP protocol stack */
+/* Using lighweight TCP/IP protocol stack*/
+/* #define RT_USING_LWIP */
+
+/* Using webserver goahead support*/
+/* #define RT_USING_WEBSERVER */
+
+/* Using ftpserver support*/
+/* #define RT_USING_FTPSERVER */
+
+/* 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	10240
+
+/* Enable SNMP protocol*/
+/* #define RT_LWIP_SNMP */
+
+/* Using DHCP*/
+/* #define RT_LWIP_DHCP */
+
+/* ip address of target*/
+#define RT_LWIP_IPADDR0	192
+#define RT_LWIP_IPADDR1	168
+#define RT_LWIP_IPADDR2	0
+#define RT_LWIP_IPADDR3	30
+
+/* gateway address of target*/
+#define RT_LWIP_GWADDR0	192
+#define RT_LWIP_GWADDR1	168
+#define RT_LWIP_GWADDR2	0
+#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
+
+/* 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	8
+
+/* 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
+
+#endif

+ 120 - 0
bsp/microblaze/startup.c

@@ -0,0 +1,120 @@
+/*
+ * 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
+ * 2006-08-31     Bernard      first implementation
+ * 2011-12-17     nl1031	   for MicroBlaze
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+//#include <AT91SAM7S.h>
+#include "board.h"
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+extern void finsh_system_init(void);
+#endif
+
+extern void rt_hw_led_flash(void);
+
+
+/*@{*/
+#ifdef __CC_ARM
+extern int Image$$RW_IRAM1$$ZI$$Limit;
+#endif
+
+#ifdef __GNUC__
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+#endif
+
+extern void rt_hw_interrupt_init(void);
+extern int  rt_application_init(void);
+#ifdef RT_USING_DEVICE
+extern rt_err_t rt_hw_serial_init(void);
+#endif
+
+/**
+ * This function will startup RT-Thread RTOS.
+ */
+void rtthread_startup(void)
+{
+	/* init hardware interrupt */
+	rt_hw_interrupt_init();
+
+	/* init board */
+	rt_hw_board_init();
+	
+	rt_show_version();
+
+	/* init tick */
+	rt_system_tick_init();
+
+	/* init kernel object */
+	rt_system_object_init();
+
+	/* init timer system */
+	rt_system_timer_init();
+
+#ifdef RT_USING_HEAP
+#ifdef __CC_ARM
+	rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x204000);
+#elif __ICCARM__
+    rt_system_heap_init(__segment_end("HEAP"), (void*)0x204000);
+#else
+	rt_system_heap_init((void*)&__bss_end, (void*)(&__bss_end+0x4000));
+#endif
+#endif
+
+	/* init scheduler system */
+	rt_system_scheduler_init();
+
+#ifdef RT_USING_HOOK /* if the hook is used */
+	/* set idle thread hook */
+	rt_thread_idle_sethook(rt_hw_led_flash);
+#endif
+
+//#ifdef RT_USING_DEVICE
+	/* init hardware serial device */
+	rt_hw_serial_init();
+	/* init all device */
+	rt_device_init_all();
+//#endif
+
+	/* init application */
+	rt_application_init();
+
+#ifdef RT_USING_FINSH
+	/* init finsh */
+	finsh_system_init();
+	finsh_set_device("uart1");
+#endif
+
+	/* init idle thread */
+	rt_thread_idle_init();
+
+	/* start scheduler */
+	rt_system_scheduler_start();
+
+	/* never reach here */
+	return ;
+}
+
+int main (void)
+{
+	/* invoke rtthread_startup */
+	rtthread_startup();
+	
+	return 0;
+}
+
+/*@}*/

+ 224 - 0
libcpu/xilinx/microblaze/context_gcc.S

@@ -0,0 +1,224 @@
+/*
+ * File      : context_gcc.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-12-17     nl1031       first implementation for MicroBlaze.
+ *
+ */
+
+#include "microbalze.inc"
+
+	.text
+    .globl		rt_interrupt_enter
+    .globl		rt_interrupt_leave
+
+/*
+ * rt_base_t rt_hw_interrupt_disable()
+ * copy from ucos-ii
+ */
+
+	.globl		rt_hw_interrupt_disable
+	.ent		rt_hw_interrupt_disable
+	.align		2
+rt_hw_interrupt_disable:
+    ADDIK   r1, r1, -4
+    SW      r4, r1, r0
+
+    MFS     r3, RMSR
+    ANDNI   r4, r3, IE_BIT
+    MTS     RMSR, r4
+
+    LW      r4, r1, r0
+    ADDIK   r1, r1, 4
+
+    AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
+    AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
+    AND     r0, r0, r0             /* NO-OP - pipeline flush                             */
+
+    RTSD    r15, 8
+    AND     r0, r0, r0
+	.end	rt_hw_interrupt_disable
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level)
+ * copy from ucos-ii
+ */
+	.globl	rt_hw_interrupt_enable
+	.ent	rt_hw_interrupt_enable
+	.align	2
+rt_hw_interrupt_enable:
+    RTSD    r15, 8
+    MTS     rMSR, r5               		/* Move the saved status from r5 into rMSR            */
+	.end	rt_hw_interrupt_enable
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
+ * r5 --> from
+ * r6 --> to
+ */
+
+	.globl rt_interrupt_from_thread
+	.globl rt_interrupt_to_thread
+	.globl rt_hw_context_switch
+	.ent rt_hw_context_switch
+	.align	2
+rt_hw_context_switch:
+	PUSH_ALL
+    MFS     r3,  RMSR                   /* save the MSR */
+    SWI     r3,  r1, STACK_RMSR
+	SWI		r1,  r5, 0					/* store sp in preempted tasks TCB */
+	LWI		r1,  r6, 0					/* get new task stack pointer */
+
+    LWI     r3,  r1, STACK_RMSR
+    ANDI    r3,  r3, IE_BIT
+    BNEI    r3,  rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
+
+    LWI     r3,  r1, STACK_RMSR
+    MTS     RMSR,r3
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+    RTSD    r15, 8
+    AND     r0,  r0, r0
+
+rt_hw_context_switch_ie:
+
+    LWI     r3,  r1, STACK_RMSR
+    ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
+    MTS     RMSR,r3
+    LWI     r3,  r1, STACK_R03
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+    RTID    r14, 0                    	/* IE bit will be set automatically */
+    AND     r0,  r0, r0
+	.end	rt_hw_context_switch
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to)
+ * r5 --> to
+ */
+	.globl rt_hw_context_switch_to
+	.ent   rt_hw_context_switch_to
+	.align	2
+rt_hw_context_switch_to:
+	LWI		r1,	 r5, 0 					/* get new task stack pointer */
+    LWI     r3,  r1, STACK_RMSR
+    ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
+    MTS     RMSR,r3
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+    RTID    r14, 0                    	/* IE bit will be set automatically */
+    AND     r0,  r0, r0
+
+	.end rt_hw_context_switch_to
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
+ */
+	.globl rt_thread_switch_interrupt_flag
+	.globl rt_hw_context_switch_interrupt
+	.ent rt_hw_context_switch_interrupt
+	.align	2
+rt_hw_context_switch_interrupt:
+	LA		r3,	r0, rt_thread_switch_interrupt_flag
+	LWI		r4, r3, 0					/* load rt_thread_switch_interrupt_flag into r4 */
+
+	ANDI	r4, r4, 1
+	BNEI	r4, _reswitch				/* if rt_thread_switch_interrupt_flag = 1 */
+
+	ADDIK	r4, r0, 1					/* set rt_thread_switch_interrupt_flag to 1 */
+	SWI		r4, r3, 0
+
+	LA		r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+	SWI		r5, r3, 0 					/* rt_interrupt_from_thread = from */
+_reswitch:
+	LA		r3, r0, rt_interrupt_to_thread	/* set rt_interrupt_to_thread */
+	SWI		r6, r3, 0 					/* rt_interrupt_to_thread = to */
+    RTSD    r15, 8
+    AND     r0, r0, r0
+	.end rt_hw_context_switch_interrupt
+
+
+    .globl     	_interrupt_handler
+	.section .text
+	.align 2
+	.ent _interrupt_handler
+	.type _interrupt_handler, @function
+
+_interrupt_handler:
+	PUSH_ALL
+    MFS     r3,  RMSR
+    ORI     r3,  r3, IE_BIT
+    SWI     r3,  r1, STACK_RMSR         	/* push MSR    */
+
+    BRLID   r15, rt_interrupt_enter
+    AND     r0,  r0, r0
+
+    BRLID   r15, rt_hw_trap_irq
+    AND     r0,  r0, r0
+
+    BRLID   r15, rt_interrupt_leave
+    AND     r0,  r0, r0
+
+	/*
+	 * if rt_thread_switch_interrupt_flag set, jump to
+	 * rt_hw_context_switch_interrupt_do and don't return
+	 */
+	LA		r3,	r0, rt_thread_switch_interrupt_flag
+	LWI		r4, r3, 0
+
+	ANDI	r4,	r4, 1
+	BNEI 	r4,	rt_hw_context_switch_interrupt_do
+
+    LWI     r3,  r1, STACK_RMSR
+    ANDNI   r3,  r3, IE_BIT
+    MTS     RMSR,r3
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+
+    RTID    r14, 0
+    AND     r0,  r0, r0
+
+/*
+ * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+ */
+rt_hw_context_switch_interrupt_do:
+	SWI		r0,  r3, 0 						/* clear rt_thread_switch_interrupt_flag */
+
+	LA		r3,  r0, rt_interrupt_from_thread
+	LW		r4,  r0, r3
+	SWI		r1,  r4, 0						/* store sp in preempted tasks's TCB */
+
+	LA		r3,  r0, rt_interrupt_to_thread
+	LW		r4,  r0, r3
+	LWI		r1,  r4, 0						/* get new task's stack pointer */
+
+    LWI     r3,  r1, STACK_RMSR
+    ANDI    r3,  r3, IE_BIT
+    BNEI    r3,  return_with_ie     	/*if IE bit set,should be use RTID (return from interrupt). */
+
+    LWI     r3,  r1, STACK_RMSR
+    MTS     RMSR,r3
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+    RTSD    r15, 8
+    AND     r0,  r0, r0
+
+return_with_ie:
+
+    LWI     r3,  r1, STACK_RMSR
+    ANDNI   r3,  r3, IE_BIT         	/* clear IE bit, prevent interrupt occur immediately*/
+    MTS     RMSR,r3
+    LWI     r3,  r1, STACK_R03
+	POP_ALL
+    ADDIK   r1,  r1, STACK_SIZE
+    RTID    r14, 0                    	/* IE bit will be set automatically */
+    AND     r0,  r0, r0
+
+.end _interrupt_handler

+ 35 - 0
libcpu/xilinx/microblaze/cpu.c

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

+ 116 - 0
libcpu/xilinx/microblaze/microbalze.inc

@@ -0,0 +1,116 @@
+/*
+ * File      : microblaze.inc
+ * 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-12-17     nl1031       first implementation for MicroBlaze.
+ *
+ */
+
+
+
+.equ    STACK_RMSR,   	0x00
+.equ    STACK_R02,    	0x04
+.equ    STACK_R03,    	0x08
+.equ    STACK_R04,    	0x0C
+.equ    STACK_R05,    	0x10
+.equ    STACK_R06,    	0x14
+.equ    STACK_R07,    	0x18
+.equ    STACK_R08,    	0x1C
+.equ    STACK_R09,    	0x20
+.equ    STACK_R10,    	0x24
+.equ    STACK_R11,    	0x28
+.equ    STACK_R12,    	0x2C
+.equ    STACK_R13,    	0x30
+.equ    STACK_R14,    	0x34
+.equ    STACK_R15,    	0x38
+.equ    STACK_R17,    	0x3C
+.equ    STACK_R18,    	0x40
+.equ    STACK_R19,    	0x44
+.equ    STACK_R20,    	0x48
+.equ    STACK_R21,    	0x4C
+.equ    STACK_R22,    	0x50
+.equ    STACK_R23,    	0x54
+.equ    STACK_R24,    	0x58
+.equ    STACK_R25,    	0x5C
+.equ    STACK_R26,    	0x60
+.equ    STACK_R27,    	0x64
+.equ    STACK_R28,    	0x68
+.equ    STACK_R29,    	0x6C
+.equ    STACK_R30,    	0x70
+.equ    STACK_R31,    	0x74
+
+.equ    STACK_SIZE,   	0x78
+.equ    IE_BIT,       	0x02
+
+.macro PUSH_ALL 
+    ADDIK   r1,  r1, -STACK_SIZE
+    SWI     r2,  r1,  STACK_R02
+    SWI     r3,  r1,  STACK_R03
+    SWI     r4,  r1,  STACK_R04
+    SWI     r5,  r1,  STACK_R05
+    SWI     r6,  r1,  STACK_R06
+    SWI     r7,  r1,  STACK_R07
+    SWI     r8,  r1,  STACK_R08
+    SWI     r9,  r1,  STACK_R09
+    SWI     r10, r1,  STACK_R10
+    SWI     r11, r1,  STACK_R11
+    SWI     r12, r1,  STACK_R12
+    SWI     r13, r1,  STACK_R13
+    SWI     r14, r1,  STACK_R14
+    SWI     r15, r1,  STACK_R15
+    SWI     r17, r1,  STACK_R17
+    SWI     r18, r1,  STACK_R18
+    SWI     r19, r1,  STACK_R19
+    SWI     r20, r1,  STACK_R20
+    SWI     r21, r1,  STACK_R21
+    SWI     r22, r1,  STACK_R22
+    SWI     r23, r1,  STACK_R23
+    SWI     r24, r1,  STACK_R24
+    SWI     r25, r1,  STACK_R25
+    SWI     r26, r1,  STACK_R26
+    SWI     r27, r1,  STACK_R27
+    SWI     r28, r1,  STACK_R28
+    SWI     r29, r1,  STACK_R29
+    SWI     r30, r1,  STACK_R30
+    SWI     r31, r1,  STACK_R31
+.endm
+
+.macro POP_ALL
+    LWI     r31, r1, STACK_R31
+    LWI     r30, r1, STACK_R30
+    LWI     r29, r1, STACK_R29
+    LWI     r28, r1, STACK_R28
+    LWI     r27, r1, STACK_R27
+    LWI     r26, r1, STACK_R26
+    LWI     r25, r1, STACK_R25
+    LWI     r24, r1, STACK_R24
+    LWI     r23, r1, STACK_R23
+    LWI     r22, r1, STACK_R22
+    LWI     r21, r1, STACK_R21
+    LWI     r20, r1, STACK_R20
+    LWI     r19, r1, STACK_R19
+    LWI     r18, r1, STACK_R18
+    LWI     r17, r1, STACK_R17
+    LWI     r15, r1, STACK_R15
+    LWI     r14, r1, STACK_R14
+    LWI     r13, r1, STACK_R13
+    LWI     r12, r1, STACK_R12
+    LWI     r11, r1, STACK_R11
+    LWI     r10, r1, STACK_R10
+    LWI     r9,  r1, STACK_R09
+    LWI     r8,  r1, STACK_R08
+    LWI     r7,  r1, STACK_R07
+    LWI     r6,  r1, STACK_R06
+    LWI     r5,  r1, STACK_R05
+    LWI     r4,  r1, STACK_R04
+    LWI     r3,  r1, STACK_R03
+    LWI     r2,  r1, STACK_R02
+.endm
+

+ 310 - 0
libcpu/xilinx/microblaze/serial.c

@@ -0,0 +1,310 @@
+/*
+ * File      : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ * 2009-05-14     Bernard      add RT-THread device interface
+ *
+ * 2011-12-17	  nl1031	   MicroBlaze
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "serial.h"
+
+typedef volatile rt_uint32_t REG32;
+struct rt_mb_uart_lite_hw
+{
+	REG32	 Rx_FIFO; 	// Receiver Holding Register
+	REG32	 Tx_FIFO; 	// Transmitter Holding Register
+	REG32	 STAT_REG; 	// Channel Status Register
+	REG32	 CTRL_REG; 	// Control Register
+};
+
+struct rt_mb_uart_lite
+{
+	struct rt_device parent;
+
+	struct rt_mb_uart_lite_hw* hw_base;
+	rt_uint16_t peripheral_id;
+	rt_uint32_t baudrate;
+
+	/* reception field */
+	rt_uint16_t save_index, read_index;
+	rt_uint8_t  rx_buffer[RT_UART_RX_BUFFER_SIZE];
+};
+#ifdef RT_USING_UART1
+struct rt_mb_uart_lite serial1;
+#endif
+
+static void rt_hw_serial_isr(void)
+{
+	unsigned int status;
+	rt_base_t level;
+	struct rt_device* device;
+	struct rt_mb_uart_lite* serial = RT_NULL;
+
+#ifdef RT_USING_UART1
+	/* serial 1 */
+	serial = &serial1;
+#endif
+	RT_ASSERT(serial != RT_NULL);
+
+	/* get generic device object */
+	device = (rt_device_t)serial;
+
+	/* disable interrupt */
+	level = rt_hw_interrupt_disable();
+
+	/* get uart status register */
+	status = serial->hw_base->STAT_REG;
+	while (status & XUL_SR_RX_FIFO_VALID_DATA)
+	{
+		/* get received character */
+		serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO;
+
+		/* move to next position */
+		serial->save_index ++;
+		if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
+			serial->save_index = 0;
+
+		/* if the next position is read index, discard this 'read char' */
+		if (serial->save_index == serial->read_index)
+		{
+			serial->read_index ++;
+			if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+				serial->read_index = 0;
+		}
+		status = serial->hw_base->STAT_REG;
+	}
+	/* enable interrupt */
+	rt_hw_interrupt_enable(level);
+
+	/* indicate to upper layer application */
+	if (device->rx_indicate != RT_NULL)
+		device->rx_indicate(device, 1);
+
+}
+
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+	struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev;
+
+	RT_ASSERT(serial != RT_NULL);
+
+	RT_ASSERT(serial->peripheral_id != XPAR_INTC_0_UARTLITE_1_VEC_ID);
+
+//	serial->hw_base->CTRL_REG = XUL_CR_FIFO_RX_RESET	| 	/* Reset Receiver      */
+//								XUL_CR_FIFO_TX_RESET;		/* Reset Transmitter   */
+
+	/* reset rx index */
+	serial->save_index = 0;
+	serial->read_index = 0;
+
+	/* reset rx buffer */
+	rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+	struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* enable UART rx interrupt */
+		serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; 		/* enable interrupt */
+
+		/* install UART handler */
+		rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t)rt_hw_serial_isr, RT_NULL);
+		rt_hw_interrupt_umask(serial->peripheral_id);
+	}
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+	struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		/* disable interrupt */
+		serial->hw_base->CTRL_REG =  0; 		/* RxReady interrupt */
+	}
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	/* point to buffer */
+	ptr = (rt_uint8_t*) buffer;
+
+	if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+	{
+		while (size)
+		{
+			/* interrupt receive */
+			rt_base_t level;
+
+			/* disable interrupt */
+			level = rt_hw_interrupt_disable();
+			if (serial->read_index != serial->save_index)
+			{
+				*ptr = serial->rx_buffer[serial->read_index];
+
+				serial->read_index ++;
+				if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
+					serial->read_index = 0;
+			}
+			else
+			{
+				/* no data in rx buffer */
+
+				/* enable interrupt */
+				rt_hw_interrupt_enable(level);
+				break;
+			}
+
+			/* enable interrupt */
+			rt_hw_interrupt_enable(level);
+
+			ptr ++; size --;
+		}
+
+		return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
+	}
+	else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
+	{
+		/* not support right now */
+		RT_ASSERT(0);
+	}
+	else
+	{
+		/* poll mode */
+		while (size)
+		{
+			/* Wait for Full Rx Buffer */
+			while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA));
+
+			/* Read Character */
+			*ptr = serial->hw_base->Rx_FIFO;
+			ptr ++;
+			size --;
+		}
+
+		return (rt_size_t)ptr - (rt_size_t)buffer;
+	}
+
+	return 0;
+}
+
+static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+	rt_uint8_t* ptr;
+	struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
+	RT_ASSERT(serial != RT_NULL);
+
+	ptr = (rt_uint8_t*) buffer;
+	if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
+	{
+		if (dev->flag & RT_DEVICE_FLAG_STREAM)
+		{
+			/* it's a stream mode device */
+			while (size)
+			{
+				/* stream mode */
+				if (*ptr == '\n')
+				{
+					while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
+					serial->hw_base->Tx_FIFO = '\r';
+				}
+
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
+
+				/* Transmit Character */
+				serial->hw_base->Tx_FIFO = *ptr;
+				ptr ++; size --;
+			}
+		}
+		else
+		{
+			while (size)
+			{
+				/* Wait for Empty Tx Buffer */
+				while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
+
+				/* Transmit Character */
+				serial->hw_base->Tx_FIFO = *ptr;
+				ptr ++; size --;
+			}
+		}
+	}
+
+	return (rt_size_t)ptr - (rt_size_t)buffer;
+}
+
+static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+	return RT_EOK;
+}
+
+rt_err_t rt_hw_serial_init()
+{
+	rt_device_t device;
+
+#ifndef RT_USING_CONSOLE
+	int Status;
+
+	/*
+	 * Initialize the UartLite driver so that it is ready to use.
+	 */
+	Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
+	if (Status != XST_SUCCESS)
+	{
+		return;
+	}
+
+#endif
+
+#ifdef RT_USING_UART1
+	device = (rt_device_t) &serial1;
+
+	/* init serial device private data */
+	serial1.hw_base 		= (struct rt_mb_uart_lite_hw*)XPAR_USB_UART_BASEADDR;
+	serial1.peripheral_id 	= XPAR_INTC_0_UARTLITE_1_VEC_ID;
+	serial1.baudrate		= 9600;
+
+	/* set device virtual interface */
+	device->init 	= rt_serial_init;
+	device->open 	= rt_serial_open;
+	device->close 	= rt_serial_close;
+	device->read 	= rt_serial_read;
+	device->write 	= rt_serial_write;
+	device->control = rt_serial_control;
+
+	/* register uart1 on device subsystem */
+	rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+#endif
+
+
+	return RT_EOK;
+}
+
+

+ 6 - 0
libcpu/xilinx/microblaze/serial.h

@@ -0,0 +1,6 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+#include "xuartlite_l.h"
+#include "xparameters.h"
+
+#endif

+ 71 - 0
libcpu/xilinx/microblaze/stack.c

@@ -0,0 +1,71 @@
+/*
+ * 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-12-17     nl1031       first implementation for MicroBlaze.
+ *
+ */
+#include <rtthread.h>
+extern   void  *_SDA_BASE_;
+extern   void  *_SDA2_BASE_;
+
+
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	unsigned long *stk;
+
+	stk 	 = (unsigned long *)stack_addr;
+	stk--;
+	stk--;
+	*stk-- = 0;								/* r31 */
+	*stk-- = 0;								/* r30 */
+	*stk-- = 0;								/* r29 */
+	*stk-- = 0;								/* r28 */
+	*stk-- = 0;								/* r27 */
+	*stk-- = 0;								/* r26 */
+	*stk-- = 0;								/* r25 */
+	*stk-- = 0;								/* r24 */
+	*stk-- = 0;								/* r23 */
+	*stk-- = 0;								/* r22 */
+	*stk-- = 0;								/* r21 */
+	*stk-- = 0;								/* r20 */
+	*stk-- = 0;								/* r19 */
+	*stk-- = 0;								/* r18 */
+	*stk-- = 0;								/* r17 */
+	*stk-- = (unsigned long)texit;			/* r15 = task return address*/
+	*stk-- = (unsigned long)tentry;			/* r14 = entry address*/
+	*stk-- = (unsigned long)&_SDA_BASE_;	/* r13 */
+	*stk-- = 0;								/* r12 */
+	*stk-- = 0;								/* r11 */
+	*stk-- = 0;								/* r10 */
+	*stk-- = 0;								/* r09 */
+	*stk-- = 0;								/* r08 */
+	*stk-- = 0;								/* r07 */
+	*stk-- = 0;								/* r06 */
+	*stk-- = (unsigned long) parameter;		/* r05 */
+	*stk-- = 0;								/* r04 */
+	*stk-- = 0;								/* r03 */
+	*stk-- = (unsigned long)&_SDA2_BASE_;	/* r02 */
+	*stk   = 2;   							/* enable interrupt */
+	return (rt_uint8_t *)stk;
+}
+

+ 211 - 0
libcpu/xilinx/microblaze/trap.c

@@ -0,0 +1,211 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-08-23     Bernard      first version
+ * 2011-12-17	  nl1031	   for MicroBlaze
+ *
+ */
+
+#include 	<rtthread.h>
+#include 	"xparameters.h"
+#include 	"xintc.h"
+#include    "xintc_i.h"
+#include    "xintc_l.h"
+
+
+#define MAX_HANDLERS  XPAR_INTC_MAX_NUM_INTR_INPUTS
+extern XIntc int_ctl; /* The instance of the Interrupt Controller */
+
+
+extern rt_uint32_t rt_interrupt_nest;
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+
+void rt_hw_interrupt_handler(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	rt_base_t index;
+
+	XIntc_Config           *CfgPtr;
+
+
+    CfgPtr = &XIntc_ConfigTable[0];
+
+
+	for (index = 0; index < MAX_HANDLERS; index ++)
+	{
+		CfgPtr->HandlerTable[index].Handler = (XInterruptHandler)rt_hw_interrupt_handler;
+	}
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrupt_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	/* disable interrupt */
+	XIntc_Disable(&int_ctl,vector);
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	XIntc_Enable(&int_ctl,vector);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	XIntc_Config           *CfgPtr;
+
+    CfgPtr = &XIntc_ConfigTable[0];
+
+	if(vector >= 0 && vector < MAX_HANDLERS)
+	{
+		if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)CfgPtr->HandlerTable[vector].Handler;
+		if (new_handler != RT_NULL) CfgPtr->HandlerTable[vector].Handler = (XInterruptHandler)new_handler;
+	}
+}
+
+/*****************************************************************************/
+/** copy from XIntc_DeviceInterruptHandler in xintc_l.c nl1031
+*
+* This function is the primary interrupt handler for the driver. It must be
+* connected to the interrupt source such that is called when an interrupt of
+* the interrupt controller is active. It will resolve which interrupts are
+* active and enabled and call the appropriate interrupt handler. It uses
+* the AckBeforeService flag in the configuration data to determine when to
+* acknowledge the interrupt. Highest priority interrupts are serviced first.
+* The driver can be configured to service only the highest priority interrupt
+* or all pending interrupts using the {XIntc_SetOptions()} function or
+* the {XIntc_SetIntrSrvOption()} function.
+*
+* This function assumes that an interrupt vector table has been previously
+* initialized.  It does not verify that entries in the table are valid before
+* calling an interrupt handler.
+*
+*
+* @return	None.
+*
+* @note
+*
+* The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile.
+* Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals
+* for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the
+* highest numbered interrupt input signal that is used.
+*
+******************************************************************************/
+
+
+void rt_hw_trap_irq(void )
+{
+	u32 intr_status;
+	u32 intr_mask = 1;
+	int intr_number;
+	volatile u32 reg;			/* used as bit bucket */
+	XIntc_Config *cfg_ptr;
+
+
+	/* Get the configuration data using the device ID */
+	cfg_ptr = &XIntc_ConfigTable[0];
+
+	/* Get the interrupts that are waiting to be serviced */
+	intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR);
+
+	/* Service each interrupt that is active and enabled by checking each
+	 * bit in the register from LSB to MSB which corresponds to an interrupt
+	 * intput signal
+	 */
+	for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++)
+	{
+		if (intr_status & 1)
+		{
+			XIntc_VectorTableEntry *table_ptr;
+
+			/* If the interrupt has been setup to acknowledge it
+			 * before servicing the interrupt, then ack it
+			 */
+			if (cfg_ptr->AckBeforeService & intr_mask)
+			{
+				XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
+			}
+
+			/* The interrupt is active and enabled, call the
+			 * interrupt handler that was setup with the specified
+			 * parameter
+			 */
+			table_ptr = &(cfg_ptr->HandlerTable[intr_number]);
+			table_ptr->Handler(table_ptr->CallBackRef);
+
+			/* If the interrupt has been setup to acknowledge it
+			 * after it has been serviced then ack it
+			 */
+			if ((cfg_ptr->AckBeforeService & intr_mask) == 0)
+			{
+				XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
+			}
+
+			/*
+			 * Read the ISR again to handle architectures with posted write
+			 * bus access issues.
+			 */
+			reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress);
+
+			/*
+			 * If only the highest priority interrupt is to be
+			 * serviced, exit loop and return after servicing
+			 * the interrupt
+			 */
+			if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION)
+			{
+				return;
+			}
+		}
+
+		/* Move to the next interrupt to check */
+		intr_mask <<= 1;
+		intr_status >>= 1;
+
+		/* If there are no other bits set indicating that all interrupts
+		 * have been serviced, then exit the loop
+		 */
+		if (intr_status == 0)
+		{
+			break;
+		}
+	}
+}
+
+