summaryrefslogtreecommitdiff
path: root/libcpu/xilinx
diff options
context:
space:
mode:
author[email protected] <[email protected]>2011-12-17 04:14:22 +0000
committer[email protected] <[email protected]>2011-12-17 04:14:22 +0000
commit08f25161d9f988eaefd37e4d06fe244bed381418 (patch)
tree61a9b5df13376536407ea824304956700781d7e7 /libcpu/xilinx
parent43ece86f1122fbc8603b9dba02e3be66522114f7 (diff)
porting for microblaze. nl1031
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1843 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu/xilinx')
-rwxr-xr-xlibcpu/xilinx/microblaze/context_gcc.S224
-rwxr-xr-xlibcpu/xilinx/microblaze/cpu.c35
-rwxr-xr-xlibcpu/xilinx/microblaze/microbalze.inc116
-rwxr-xr-xlibcpu/xilinx/microblaze/serial.c310
-rwxr-xr-xlibcpu/xilinx/microblaze/serial.h6
-rwxr-xr-xlibcpu/xilinx/microblaze/stack.c71
-rwxr-xr-xlibcpu/xilinx/microblaze/trap.c211
7 files changed, 973 insertions, 0 deletions
diff --git a/libcpu/xilinx/microblaze/context_gcc.S b/libcpu/xilinx/microblaze/context_gcc.S
new file mode 100755
index 0000000000..74b7f50a51
--- /dev/null
+++ b/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
diff --git a/libcpu/xilinx/microblaze/cpu.c b/libcpu/xilinx/microblaze/cpu.c
new file mode 100755
index 0000000000..50a0e34dcd
--- /dev/null
+++ b/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);
+}
+
diff --git a/libcpu/xilinx/microblaze/microbalze.inc b/libcpu/xilinx/microblaze/microbalze.inc
new file mode 100755
index 0000000000..19128df3fc
--- /dev/null
+++ b/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
+
diff --git a/libcpu/xilinx/microblaze/serial.c b/libcpu/xilinx/microblaze/serial.c
new file mode 100755
index 0000000000..be43c5ead1
--- /dev/null
+++ b/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;
+}
+
+
diff --git a/libcpu/xilinx/microblaze/serial.h b/libcpu/xilinx/microblaze/serial.h
new file mode 100755
index 0000000000..090efa84e5
--- /dev/null
+++ b/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
diff --git a/libcpu/xilinx/microblaze/stack.c b/libcpu/xilinx/microblaze/stack.c
new file mode 100755
index 0000000000..fff1348ee3
--- /dev/null
+++ b/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;
+}
+
diff --git a/libcpu/xilinx/microblaze/trap.c b/libcpu/xilinx/microblaze/trap.c
new file mode 100755
index 0000000000..3b3f98d105
--- /dev/null
+++ b/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;
+ }
+ }
+}
+
+