summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
author[email protected] <[email protected]>2010-06-26 03:47:03 +0000
committer[email protected] <[email protected]>2010-06-26 03:47:03 +0000
commit360095ecb149cdca6eec2c9e92e978bca6462ab8 (patch)
tree2b1ecdaf5719faa44f741aeea348603a0bf7e714 /libcpu
parent77b375741e95d31c11609bf7fdc8c16fa88733ec (diff)
add sep4020 porting
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@776 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/sep4020/clk.c112
-rw-r--r--libcpu/arm/sep4020/context_rvds.S107
-rw-r--r--libcpu/arm/sep4020/cpu.c42
-rw-r--r--libcpu/arm/sep4020/interrupt.c107
-rw-r--r--libcpu/arm/sep4020/serial.c281
-rw-r--r--libcpu/arm/sep4020/serial.h56
-rw-r--r--libcpu/arm/sep4020/stack.c61
-rw-r--r--libcpu/arm/sep4020/start_rvds.S374
-rw-r--r--libcpu/arm/sep4020/trap.c66
9 files changed, 1206 insertions, 0 deletions
diff --git a/libcpu/arm/sep4020/clk.c b/libcpu/arm/sep4020/clk.c
new file mode 100644
index 0000000000..7b298ea825
--- /dev/null
+++ b/libcpu/arm/sep4020/clk.c
@@ -0,0 +1,112 @@
+/*
+ * 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
+ * 2010-03-20 zchong first version
+ */
+
+#include <rtthread.h>
+#include "sep4020.h"
+
+#define CLK_IN 4000000 /* Fin = 4.00MHz */
+#define SYSCLK 72000000 /* system clock we want */
+
+#define CLK_ESRAM 0
+#define CLK_LCDC 1
+#define CLK_PWM 2
+#define CLK_DMAC 3
+#define CLK_EMI 4
+#define CLK_MMCSD 5
+#define CLK_SSI 7
+#define CLK_UART0 8
+#define CLK_UART1 9
+#define CLK_UART2 10
+#define CLK_UART3 11
+#define CLK_USB 12
+#define CLK_MAC 13
+#define CLK_SMC 14
+#define CLK_I2C 15
+#define CLK_GPT 16
+
+static void rt_hw_set_system_clock(void)
+{
+ rt_uint8_t pv;
+
+ /* pv value*/
+ pv = SYSCLK/2/CLK_IN;
+ /* go to normal mode*/
+ PMC_PMDR = 0x01;
+ /* set the clock */
+ PMC_PMCR = 0x4000 | pv;
+ /* trige configurate*/
+ PMC_PMCR = 0xc000 | pv;
+}
+
+static void rt_hw_set_usb_clock(void)
+{
+ /* set the clock */
+ PMC_PUCR = 0x000c;
+ /* trige configurate*/
+ PMC_PMCR = 0x800c;
+
+}
+
+/**
+ * @brief System Clock Configuration
+ */
+void rt_hw_clock_init(void)
+{
+ /* set system clock */
+ rt_hw_set_system_clock();
+ /* set usb clock */
+ rt_hw_set_usb_clock();
+}
+
+/**
+ * @brief Get system clock
+ */
+rt_uint32_t rt_hw_get_clock(void)
+{
+ rt_uint32_t val;
+ rt_uint8_t pv, pd, npd;
+
+ /* get PMCR value */
+ val = PMC_PMCR;
+ /* get NPD */
+ npd = (val >> 14) & 0x01;
+ /* get PD */
+ pd = (val >> 10) & 0x0f;
+ /* get PV */
+ pv = val & 0x7f;
+ /* caculate the system clock */
+ if(npd)
+ val = 2 * CLK_IN * pv;
+ else
+ val = CLK_IN * pv / (pd + 1);
+
+ return(val);
+}
+
+/**
+ * @brief Enable module clock
+ */
+ void rt_hw_enable_module_clock(rt_uint8_t module)
+ {
+
+ }
+
+/**
+ * @brief Disable module clock
+ */
+ void rt_hw_disable_module_clock(rt_uint8_t module)
+ {
+
+ }
+
diff --git a/libcpu/arm/sep4020/context_rvds.S b/libcpu/arm/sep4020/context_rvds.S
new file mode 100644
index 0000000000..82c5adc574
--- /dev/null
+++ b/libcpu/arm/sep4020/context_rvds.S
@@ -0,0 +1,107 @@
+;/*
+; * File : context_rvds.S
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; */
+
+NOINT EQU 0xc0 ; disable interrupt in psr
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ ARM
+ REQUIRE8
+ PRESERVE8
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable PROC
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, cpsr
+ ORR r1, r0, #NOINT
+ MSR cpsr_c, r1
+ BX lr
+ ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable PROC
+ EXPORT rt_hw_interrupt_enable
+ MSR cpsr_c, r0
+ BX lr
+ ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch PROC
+ EXPORT rt_hw_context_switch
+ STMFD sp!, {lr} ; push pc (lr should be pushed in place of PC)
+ STMFD sp!, {r0-r12, lr} ; push lr & register file
+
+ MRS r4, cpsr
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+rt_hw_context_switch_to PROC
+ EXPORT rt_hw_context_switch_to
+ LDR sp, [r0] ; get new task stack pointer
+
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+rt_hw_context_switch_interrupt PROC
+ EXPORT rt_hw_context_switch_interrupt
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrput_flag to 1
+ STR r3, [r2]
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+ BX lr
+ ENDP
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/sep4020/cpu.c b/libcpu/arm/sep4020/cpu.c
new file mode 100644
index 0000000000..1905da812e
--- /dev/null
+++ b/libcpu/arm/sep4020/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard first version
+ */
+
+#include <rtthread.h>
+
+
+/**
+ * @addtogroup AT91SAM7X
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/sep4020/interrupt.c b/libcpu/arm/sep4020/interrupt.c
new file mode 100644
index 0000000000..810e0185b7
--- /dev/null
+++ b/libcpu/arm/sep4020/interrupt.c
@@ -0,0 +1,107 @@
+/*
+ * 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
+ * 2010-03-17 zchong SEP4020
+ */
+
+#include <rtthread.h>
+#include "sep4020.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;
+
+/**
+ * @addtogroup SEP4020
+ */
+/*@{*/
+
+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()
+{
+ register rt_uint32_t idx;
+
+ /* disable all interrupts */
+ INTC_IER = 0x0;
+
+ /* mask all interrupts */
+ INTC_IMR = 0xFFFFFFFF;
+
+ /* init exceptions table */
+ for(idx=0; idx < MAX_HANDLERS; idx++)
+ {
+ isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handler;
+ }
+
+ /* init interrupt nest, and context in thread sp */
+ rt_interrupt_nest = 0;
+ rt_interrupt_from_thread = 0;
+ rt_interrupt_to_thread = 0;
+ rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+ INTC_IMR |= 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+ /* un-mask interrupt */
+ if ((vector == INT_NOTUSED0) || (vector == INT_NOTUSED16))
+ {
+ rt_kprintf("Interrupt vec %d is not used!\n", vector);
+ // while(1);
+ }
+ else if (vector == INTGLOBAL)
+ INTC_IMR = 0x0;
+ else
+ INTC_IMR &= ~(1 << vector);
+
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+ if(vector >= 0 && vector < MAX_HANDLERS)
+ {
+ if (*old_handler != RT_NULL) *old_handler = isr_table[vector];
+ if (new_handler != RT_NULL) isr_table[vector] = new_handler;
+ }
+}
+
+/*@}*/
diff --git a/libcpu/arm/sep4020/serial.c b/libcpu/arm/sep4020/serial.c
new file mode 100644
index 0000000000..7f50348335
--- /dev/null
+++ b/libcpu/arm/sep4020/serial.c
@@ -0,0 +1,281 @@
+/*
+ * File : serial.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 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
+ * 2009-02-05 Bernard first version
+ * 2009-10-25 Bernard fix rt_serial_read bug when there is no data
+ * in the buffer.
+ * 2010-03-29 Bernard cleanup code.
+ * 2010-06-14 zchong for sep4020
+ */
+
+#include "serial.h"
+
+/**
+ * @addtogroup SEP4020
+ */
+/*@{*/
+
+/* RT-Thread Device Interface */
+static rt_err_t rt_serial_init (rt_device_t dev)
+{
+ struct serial_device* uart = (struct serial_device*) dev->private;
+
+ 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;
+}
+
+static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ return RT_EOK;
+}
+
+static rt_err_t rt_serial_close(rt_device_t dev)
+{
+ 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->private;
+
+ if (dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* interrupt mode Rx */
+ while (size)
+ {
+ rt_base_t level;
+
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ if (uart->int_rx->read_index != uart->int_rx->save_index)
+ {
+ /* read a character */
+ *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
+ size--;
+
+ /* move to next position */
+ uart->int_rx->read_index ++;
+ if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
+ uart->int_rx->read_index = 0;
+ }
+ else
+ {
+ /* set error code */
+ err_code = -RT_EEMPTY;
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ break;
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+ }
+ }
+ else
+ {
+ /* polling mode */
+ while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
+ {
+ while (uart->uart_device->lsr & USTAT_RCV_READY)
+ {
+ *ptr = uart->uart_device->dlbl_rxfifo_txfifo & 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->private;
+
+ 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->lsr & USTAT_TXB_EMPTY));
+ uart->uart_device->dlbl_rxfifo_txfifo = '\r';
+ }
+
+ while (!(uart->uart_device->lsr & USTAT_TXB_EMPTY));
+ uart->uart_device->dlbl_rxfifo_txfifo = (*ptr & 0x1FF);
+
+ ++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)
+{
+// struct serial_device* uart;
+
+ RT_ASSERT(dev != RT_NULL);
+
+// uart = (struct serial_device*)dev->private;
+ 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 for SEP4020
+ */
+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->private = 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)
+{
+ rt_base_t level;
+ struct serial_device* uart = (struct serial_device*) device->private;
+
+ /* interrupt mode receive */
+ RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
+
+ /* save on rx buffer */
+ while (uart->uart_device->lsr & USTAT_RCV_READY)
+ {
+ /* disable interrupt */
+ level = rt_hw_interrupt_disable();
+
+ uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->dlbl_rxfifo_txfifo & 0xff;
+ 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);
+ }
+
+ /* 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);
+ }
+}
+
+
+/*@}*/
diff --git a/libcpu/arm/sep4020/serial.h b/libcpu/arm/sep4020/serial.h
new file mode 100644
index 0000000000..391cbe16e9
--- /dev/null
+++ b/libcpu/arm/sep4020/serial.h
@@ -0,0 +1,56 @@
+#ifndef __RT_SERIAL_H__
+#define __RT_SERIAL_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+
+#define USTAT_RCV_READY 0x01 /* receive data ready */
+#define USTAT_TXB_EMPTY 0x20 /* tx buffer empty */
+#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;
+};
+
+/* serial port registers */
+typedef struct uartport
+{
+ rt_uint32_t dlbl_rxfifo_txfifo;
+ rt_uint32_t dlbh_ier;
+ rt_uint32_t iir_fcr;
+ rt_uint32_t lcr;
+ rt_uint32_t mcr;
+ rt_uint32_t lsr;
+ rt_uint32_t msr;
+}uartport;
+
+struct serial_device
+{
+ /* uart hardware registers */
+ 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
+
diff --git a/libcpu/arm/sep4020/stack.c b/libcpu/arm/sep4020/stack.c
new file mode 100644
index 0000000000..6060b63722
--- /dev/null
+++ b/libcpu/arm/sep4020/stack.c
@@ -0,0 +1,61 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-23 Bernard the first version
+ */
+#include <rtthread.h>
+
+#define SVCMODE 0x13
+
+/**
+ * @addtogroup AT91SAM7
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+ rt_uint8_t *stack_addr, void *texit)
+{
+ unsigned long *stk;
+
+ stk = (unsigned long *)stack_addr;
+ *(stk) = (unsigned long)tentry; /* entry point */
+ *(--stk) = (unsigned long)texit; /* lr */
+ *(--stk) = 0; /* r12 */
+ *(--stk) = 0; /* r11 */
+ *(--stk) = 0; /* r10 */
+ *(--stk) = 0; /* r9 */
+ *(--stk) = 0; /* r8 */
+ *(--stk) = 0; /* r7 */
+ *(--stk) = 0; /* r6 */
+ *(--stk) = 0; /* r5 */
+ *(--stk) = 0; /* r4 */
+ *(--stk) = 0; /* r3 */
+ *(--stk) = 0; /* r2 */
+ *(--stk) = 0; /* r1 */
+ *(--stk) = (unsigned long)parameter; /* r0 : argument */
+ *(--stk) = SVCMODE; /* cpsr */
+ *(--stk) = SVCMODE; /* spsr */
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/sep4020/start_rvds.S b/libcpu/arm/sep4020/start_rvds.S
new file mode 100644
index 0000000000..6de4ee54a8
--- /dev/null
+++ b/libcpu/arm/sep4020/start_rvds.S
@@ -0,0 +1,374 @@
+;==============================================================================================
+; star_rvds.s for Keil MDK 4.10
+;
+; SEP4020 start up code
+;
+; Change Logs:
+; Date Author Notes
+; 2010-03-17 zchong
+;=============================================================================================
+
+;
+
+PMU_PLTR EQU 0x10001000 ; PLL���ȶ�����ʱ��
+PMU_PMCR EQU 0x10001004 ; ϵͳ��ʱ��PLL�Ŀ��ƼĴ���
+PMU_PUCR EQU 0x10001008 ; USBʱ��PLL�Ŀ��ƼĴ���
+PMU_PCSR EQU 0x1000100C ; �ڲ�ģ��ʱ��Դ�����Ŀ��ƼĴ���
+PMU_PDSLOW EQU 0x10001010 ; SLOW״̬��ʱ�ӵķ�Ƶ����
+PMU_PMDR EQU 0x10001014 ; оƬ����ģʽ�Ĵ���
+PMU_RCTR EQU 0x10001018 ; Reset���ƼĴ���
+PMU_CLRWAKUP EQU 0x1000101C ; WakeUp����Ĵ���
+
+RTC_CTR EQU 0x1000200C ; RTC���ƼĴ���
+
+INTC_IER EQU 0x10000000 ; IRQ�ж������Ĵ���
+INTC_IMR EQU 0x10000008 ; IRQ�ж����μĴ���
+INTC_IFSR EQU 0x10000030 ; IRQ�ж�����״̬�Ĵ���
+INTC_FIER EQU 0x100000C0 ; FIQ�ж������Ĵ���
+INTC_FIMR EQU 0x100000C4 ; FIQ�ж����μĴ���
+
+EMI_CSACONF EQU 0x11000000 ; CSA�������üĴ���
+EMI_CSECONF EQU 0x11000010 ; CSE�������üĴ���
+EMI_CSFCONF EQU 0x11000014 ; CSF�������üĴ���
+EMI_SDCONF1 EQU 0x11000018 ; SDRAMʱ�����üĴ���1
+EMI_SDCONF2 EQU 0x1100001C ; SDRAMʱ�����üĴ���2, SDRAM��ʼ���õ���������Ϣ
+EMI_REMAPCONF EQU 0x11000020 ; Ƭѡ�ռ估��ַӳ��REMAP���üĴ���
+
+Mode_USR EQU 0x10
+Mode_FIQ EQU 0x11
+Mode_IRQ EQU 0x12
+Mode_SVC EQU 0x13
+Mode_ABT EQU 0x17
+Mode_UND EQU 0x1B
+Mode_SYS EQU 0x1F
+
+I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
+F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
+NOINT EQU 0xc0
+MASK_MODE EQU 0x0000003F
+MODE_SVC32 EQU 0x00000013
+
+; Internal Memory Base Addresses
+FLASH_BASE EQU 0x20000000
+RAM_BASE EQU 0x04000000
+
+; Stack
+UND_Stack_Size EQU 0x00000000
+SVC_Stack_Size EQU 0x00000400
+ABT_Stack_Size EQU 0x00000000
+FIQ_Stack_Size EQU 0x00000000
+IRQ_Stack_Size EQU 0x00000100
+USR_Stack_Size EQU 0x00000000
+
+ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+ FIQ_Stack_Size + IRQ_Stack_Size)
+
+ AREA STACK, NOINIT, READWRITE, ALIGN=3
+
+Stack_Mem SPACE USR_Stack_Size
+__initial_sp SPACE ISR_Stack_Size
+Stack_Top
+
+; Heap
+Heap_Size EQU 0x00000000
+
+ AREA HEAP, NOINIT, READWRITE, ALIGN=3
+__heap_base
+Heap_Mem SPACE Heap_Size
+__heap_limit
+
+
+ PRESERVE8
+
+; Area Definition and Entry Point
+; Startup Code must be linked first at Address at which it expects to run.
+
+ AREA RESET, CODE, READONLY
+ ARM
+
+; Exception Vectors
+; Mapped to Address 0.
+; Absolute addressing mode must be used.
+; Dummy Handlers are implemented as infinite loops which can be modified.
+
+Vectors LDR PC,Reset_Addr
+ LDR PC,Undef_Addr
+ LDR PC,SWI_Addr
+ LDR PC,PAbt_Addr
+ LDR PC,DAbt_Addr
+ NOP ; Reserved Vector
+ LDR PC,IRQ_Addr
+ LDR PC,FIQ_Addr
+
+Reset_Addr DCD Reset_Handler
+Undef_Addr DCD Undef_Handler
+SWI_Addr DCD SWI_Handler
+PAbt_Addr DCD PAbt_Handler
+DAbt_Addr DCD DAbt_Handler
+ DCD 0 ; Reserved Address
+IRQ_Addr DCD IRQ_Handler
+FIQ_Addr DCD FIQ_Handler
+
+Undef_Handler B Undef_Handler
+SWI_Handler B SWI_Handler
+PAbt_Handler B PAbt_Handler
+DAbt_Handler B DAbt_Handler
+FIQ_Handler B FIQ_Handler
+
+
+; Reset Handler
+
+ EXPORT Reset_Handler
+Reset_Handler
+
+;****************************************************************
+;* �رտ��Ź�
+;****************************************************************
+ LDR R0,=RTC_CTR
+ LDR R1,=0x0
+ STR R1,[R0]
+
+;****************************************************************
+;* ���ж�
+;****************************************************************
+ MRS R0, CPSR
+ BIC R0, R0, #MASK_MODE
+ ORR R0, R0, #MODE_SVC32
+ ORR R0, R0, #I_Bit
+ ORR R0, R0, #F_Bit
+ MSR CPSR_c, r0
+
+ LDR R0,=INTC_IER
+ LDR R1,=0x0
+ STR R1,[R0]
+ LDR R0,=INTC_IMR
+ LDR R1,=0xFFFFFFFF
+ STR R1,[R0]
+
+ LDR R0,=INTC_FIER
+ LDR R1,=0x0
+ STR R1,[R0]
+ LDR R0,=INTC_FIMR
+ LDR R1,=0x0F
+ STR R1,[R0]
+
+;****************************************************************
+;* ��ʼ��PMUģ��, ����ϵͳʱ��
+;****************************************************************
+ LDR R4, =PMU_PCSR ; ������ģ��ʱ��
+ LDR R5, =0x0001ffff
+ STR R5, [ R4 ]
+
+ LDR R4, =PMU_PLTR ; ����PLL�ȶ�����ʱ��Ϊ����ֵ50us*100M.
+ LDR R5, =0x00fa00fa
+ STR R5, [ R4 ]
+
+ LDR R4, =PMU_PMDR ; ��SLOWģʽ����NORMALģʽ
+ LDR R5, =0x00000001
+ STR R5, [ R4 ]
+
+ LDR R4, =PMU_PMCR ; ����ϵͳʱ��Ϊ72MHz 2*Fin*9=2*4*9=72MHz
+ LDR R5, =0x00004009 ; MFCN 0->1 trigger PLL to reconfigure event when mode isn''t SLOW
+ STR R5, [ R4 ]
+ LDR R4, =PMU_PMCR ;
+ LDR R5, =0x0000c009
+ STR R5, [ R4 ]
+
+;****************************************************************
+;* ��ʼ��EMI
+;****************************************************************
+; LDR R4, =EMI_CSACONF ; CSAƬѡʱ���������
+; LDR R5, =0x08a6a6a1
+; STR R5, [ R4 ]
+
+; LDR R4, =EMI_CSECONF ; CSEƬѡʱ���������,�������
+; LDR R5, =0x8cfffff1
+; STR R5, [ R4 ]
+
+; LDR R4, =EMI_SDCONF1 ; SDRAM��������1
+; LDR R5, =0x1E104177
+; STR R5, [ R4 ]
+
+; LDR R4, =EMI_SDCONF2 ; SDRAM��������2
+; LDR R5, =0x80001860
+; STR R5, [ R4 ]
+
+
+; Copy Exception Vectors to Internal RAM
+
+ IF :DEF:RAM_INTVEC
+ ADR R8, Vectors ; Source
+ LDR R9, =RAM_BASE ; Destination
+ LDMIA R8!, {R0-R7} ; Load Vectors
+ STMIA R9!, {R0-R7} ; Store Vectors
+ LDMIA R8!, {R0-R7} ; Load Handler Addresses
+ STMIA R9!, {R0-R7} ; Store Handler Addresses
+ ENDIF
+
+
+; Remap on-chip RAM to address 0
+
+ IF :DEF:REMAP
+ LDR R0, =EMI_REMAPCONF
+ MOV R1, #0x80000000
+ STR R1, [R0, #0] ; Remap
+ ENDIF
+
+
+; Setup Stack for each mode
+
+ LDR R0, =Stack_Top
+
+; Enter Undefined Instruction Mode and set its Stack Pointer
+ MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
+ MOV SP, R0
+ SUB R0, R0, #UND_Stack_Size
+
+; Enter Abort Mode and set its Stack Pointer
+ MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
+ MOV SP, R0
+ SUB R0, R0, #ABT_Stack_Size
+
+; Enter FIQ Mode and set its Stack Pointer
+ MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
+ MOV SP, R0
+ SUB R0, R0, #FIQ_Stack_Size
+
+; Enter IRQ Mode and set its Stack Pointer
+ MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
+ MOV SP, R0
+ SUB R0, R0, #IRQ_Stack_Size
+
+; Enter Supervisor Mode and set its Stack Pointer
+ MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
+ MOV SP, R0
+ SUB R0, R0, #SVC_Stack_Size
+
+; Enter User Mode and set its Stack Pointer
+ ; MSR CPSR_c, #Mode_USR
+ IF :DEF:__MICROLIB
+
+ EXPORT __initial_sp
+
+ ELSE
+
+ ; No usr mode stack here.
+ ;MOV SP, R0
+ ;SUB SL, SP, #USR_Stack_Size
+
+ ENDIF
+
+
+; Enter the C code
+
+ IMPORT __main
+ LDR R0, =__main
+ BX R0
+
+ IMPORT rt_interrupt_enter
+ IMPORT rt_interrupt_leave
+ IMPORT rt_thread_switch_interrput_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_hw_trap_irq
+ IMPORT rt_hw_trap_abort
+ IMPORT rt_interrupt_nest
+
+Abort_Handler PROC
+ EXPORT Abort_Handler
+ STMFD SP!, {R0-R12,LR}
+ LDR R0, =rt_interrupt_nest
+ LDR R1, [R0]
+ CMP R1, #0
+DeadLoop BHI DeadLoop ; Abort happened in irq mode, halt system.
+ BL rt_interrupt_enter
+ BL rt_hw_trap_abort
+ BL rt_interrupt_leave
+ B SWITCH
+ ENDP
+
+IRQ_Handler PROC
+ EXPORT IRQ_Handler
+ STMFD SP!, {R0-R12,LR}
+ BL rt_interrupt_enter
+ BL rt_hw_trap_irq
+ BL rt_interrupt_leave
+
+ ; if rt_thread_switch_interrput_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+SWITCH
+ LDR R0, =rt_thread_switch_interrput_flag
+ LDR R1, [R0]
+ CMP R1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ LDMFD SP!, {R0-R12,LR}
+ SUBS PC, LR, #4
+ ENDP
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+rt_hw_context_switch_interrupt_do PROC
+ EXPORT rt_hw_context_switch_interrupt_do
+ MOV r1, #0 ; clear flag
+ STR r1, [r0]
+
+ LDMFD sp!, {r0-r12,lr}; reload saved registers
+ STMFD sp!, {r0-r3} ; save r0-r3
+ MOV r1, sp
+ ADD sp, sp, #16 ; restore sp
+ SUB r2, lr, #4 ; save old task's pc to r2
+
+ MRS r3, spsr ; get cpsr of interrupt thread
+
+ ; switch to SVC mode and no interrupt
+ MSR cpsr_c, #I_Bit:OR:F_Bit:OR:Mode_SVC
+
+ STMFD sp!, {r2} ; push old task's pc
+ STMFD sp!, {r4-r12,lr}; push old task's lr,r12-r4
+ MOV r4, r1 ; Special optimised code below
+ MOV r5, r3
+ LDMFD r4!, {r0-r3}
+ STMFD sp!, {r0-r3} ; push old task's r3-r0
+ STMFD sp!, {r5} ; push old task's cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push old task's spsr
+
+ LDR r4, =rt_interrupt_from_thread
+ LDR r5, [r4]
+ STR sp, [r5] ; store sp in preempted tasks's TCB
+
+ LDR r6, =rt_interrupt_to_thread
+ LDR r6, [r6]
+ LDR sp, [r6] ; get new task's stack pointer
+
+ LDMFD sp!, {r4} ; pop new task's spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task's psr
+ MSR cpsr_cxsf, r4
+
+ LDMFD sp!, {r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc
+ ENDP
+
+ IF :DEF:__MICROLIB
+
+ EXPORT __heap_base
+ EXPORT __heap_limit
+
+ ELSE
+; User Initial Stack & Heap
+ AREA |.text|, CODE, READONLY
+
+ IMPORT __use_two_region_memory
+ EXPORT __user_initial_stackheap
+__user_initial_stackheap
+
+ LDR R0, = Heap_Mem
+ LDR R1, = (Stack_Mem + IRQ_Stack_Size)
+ LDR R2, = (Heap_Mem + Heap_Size)
+ LDR R3, = Stack_Mem
+ BX LR
+ ENDIF
+
+ END
diff --git a/libcpu/arm/sep4020/trap.c b/libcpu/arm/sep4020/trap.c
new file mode 100644
index 0000000000..cad14e88fc
--- /dev/null
+++ b/libcpu/arm/sep4020/trap.c
@@ -0,0 +1,66 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2006-08-25 Bernard first version
+ * 2010-03-18 zchong for sep4020
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "sep4020.h"
+
+/**
+ * @addtogroup SEP4020
+ */
+/*@{*/
+
+extern rt_isr_handler_t isr_table[];
+
+void rt_hw_trap_irq()
+{
+ rt_uint32_t intstat,intnum;
+ rt_uint8_t i = 0;
+ rt_isr_handler_t isr_func;
+
+ /* get interrupt source */
+ intstat = INTC_IFSR;
+
+ intnum = intstat;
+ if (intstat == INTGLOBAL) return;
+
+ while(intnum != 0x00000001)
+ {
+ intnum = intnum>>1;
+ i++;
+ }
+ /* get interrupt service routine */
+ isr_func = isr_table[i];
+
+ /* turn to interrupt service routine */
+ isr_func(intstat);
+
+}
+
+void rt_hw_trap_fiq()
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+extern struct rt_thread* rt_current_thread;
+void rt_hw_trap_abort()
+{
+ rt_kprintf("Abort occured!!! Thread [%s] suspended.\n",rt_current_thread->name);
+ rt_thread_suspend(rt_current_thread);
+ rt_schedule();
+
+}
+/*@}*/