summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorqiuyiuestc <[email protected]>2009-12-26 10:10:50 +0000
committerqiuyiuestc <[email protected]>2009-12-26 10:10:50 +0000
commit6d9100da2e6deb09d72c892fc5f376828f1d81bd (patch)
treeebb8fd9c7e64e0f3d3a8de880d62337f2a7907ae /libcpu
parentd65e9dd6109a62e65ce24130dd9781bea3c48cd4 (diff)
support GCC compiler for LM3S platform
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@233 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/lm3s/context_gcc.S164
-rw-r--r--libcpu/arm/lm3s/start_gcc.c242
2 files changed, 406 insertions, 0 deletions
diff --git a/libcpu/arm/lm3s/context_gcc.S b/libcpu/arm/lm3s/context_gcc.S
new file mode 100644
index 0000000000..04d45c1327
--- /dev/null
+++ b/libcpu/arm/lm3s/context_gcc.S
@@ -0,0 +1,164 @@
+/*
+ * File : context_gcc.S
+ * 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-10-11 Bernard first version
+ */
+
+/**
+ * @addtogroup STM32
+ */
+/*@{*/
+
+.cpu cortex-m3
+.fpu softvfp
+.syntax unified
+.thumb
+.text
+
+.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
+.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
+.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
+.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.global rt_hw_interrupt_disable
+.type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.global rt_hw_interrupt_enable
+.type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+ MSR PRIMASK, r0
+ BX LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.global rt_hw_context_switch_interrupt
+.type rt_hw_context_switch_interrupt, %function
+.global rt_hw_context_switch
+.type rt_hw_context_switch, %function
+
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+ /* set rt_thread_switch_interrput_flag to 1 */
+ LDR r2, =rt_thread_switch_interrput_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #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]
+
+ LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+
+/* r0 --> swith from thread stack
+ * r1 --> swith to thread stack
+ * psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+ */
+.global rt_hw_pend_sv
+.type rt_hw_pend_sv, %function
+rt_hw_pend_sv:
+ /* disable interrupt to protect context switch */
+ MRS r2, PRIMASK
+ CPSID I
+
+ /* get rt_thread_switch_interrupt_flag */
+ LDR r0, =rt_thread_switch_interrput_flag
+ LDR r1, [r0]
+ CBZ r1, pendsv_exit /* pendsv already handled */
+
+ /* clear rt_thread_switch_interrput_flag to 0 */
+ MOV r1, #0x00
+ STR r1, [r0]
+
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CBZ r1, swtich_to_thread /* skip register save at the first time */
+
+ MRS r1, psp /* get from thread stack pointer */
+ STMFD r1!, {r4 - r11} /* push r4 - r11 register */
+ LDR r0, [r0]
+ STR r1, [r0] /* update from thread stack pointer */
+
+swtich_to_thread:
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] /* load thread stack pointer */
+
+ LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
+ MSR psp, r1 /* update stack pointer */
+
+pendsv_exit:
+ /* restore interrupt */
+ MSR PRIMASK, r2
+
+ ORR lr, lr, #0x04
+ BX lr
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.global rt_hw_context_switch_to
+.type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ /* set from thread to 0 */
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ /* set interrupt flag to 1 */
+ LDR r1, =rt_thread_switch_interrput_flag
+ MOV r0, #1
+ STR r0, [r1]
+
+ /* set the PendSV exception priority */
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ STR r1, [r0]
+
+ LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ CPSIE I /* enable interrupts at processor level */
+
+ /* never reach here! */
+
+/* compatible with old version */
+.global rt_hw_interrupt_thread_switch
+.type rt_hw_interrupt_thread_switch, %function
+rt_hw_interrupt_thread_switch:
+ BX lr
+ NOP
diff --git a/libcpu/arm/lm3s/start_gcc.c b/libcpu/arm/lm3s/start_gcc.c
new file mode 100644
index 0000000000..fa1398e35c
--- /dev/null
+++ b/libcpu/arm/lm3s/start_gcc.c
@@ -0,0 +1,242 @@
+//*****************************************************************************
+//
+// startup.c - Boot code for Stellaris.
+//
+// Copyright (c) 2005-2008 Luminary Micro, Inc. All rights reserved.
+//
+// Software License Agreement
+//
+// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
+// exclusively on LMI's microcontroller products.
+//
+// The software is owned by LMI and/or its suppliers, and is protected under
+// applicable copyright laws. All rights are reserved. You may not combine
+// this software with "viral" open-source software in order to form a larger
+// program. Any use in violation of the foregoing restrictions may subject
+// the user to criminal sanctions under applicable laws, as well as to civil
+// liability for the breach of the terms and conditions of this license.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2752 of the Stellaris Peripheral Driver Library.
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// Forward declaration of the default fault handlers.
+//
+//*****************************************************************************
+void ResetISR(void);
+static void NmiSR(void);
+static void FaultISR(void);
+static void IntDefaultHandler(void);
+
+//*****************************************************************************
+//
+// The entry point for the application.
+//
+//*****************************************************************************
+extern int main(void);
+
+//*****************************************************************************
+//
+// Reserve space for the system stack.
+//
+//*****************************************************************************
+#ifndef STACK_SIZE
+#define STACK_SIZE 64
+#endif
+static unsigned long pulStack[STACK_SIZE];
+
+//*****************************************************************************
+//
+// The minimal vector table for a Cortex M3. Note that the proper constructs
+// must be placed on this to ensure that it ends up at physical address
+// 0x0000.0000.
+//
+//*****************************************************************************
+__attribute__ ((section(".isr_vector")))
+void (* const g_pfnVectors[])(void) =
+{
+ (void (*)(void))((unsigned long)pulStack + sizeof(pulStack)),
+ // The initial stack pointer
+ ResetISR, // The reset handler
+ NmiSR, // The NMI handler
+ FaultISR, // The hard fault handler
+ IntDefaultHandler, // The MPU fault handler
+ IntDefaultHandler, // The bus fault handler
+ IntDefaultHandler, // The usage fault handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ IntDefaultHandler, // SVCall handler
+ IntDefaultHandler, // Debug monitor handler
+ 0, // Reserved
+ IntDefaultHandler, // The PendSV handler
+ IntDefaultHandler, // The SysTick handler
+ IntDefaultHandler, // GPIO Port A
+ IntDefaultHandler, // GPIO Port B
+ IntDefaultHandler, // GPIO Port C
+ IntDefaultHandler, // GPIO Port D
+ IntDefaultHandler, // GPIO Port E
+ IntDefaultHandler, // UART0 Rx and Tx
+ IntDefaultHandler, // UART1 Rx and Tx
+ IntDefaultHandler, // SSI Rx and Tx
+ IntDefaultHandler, // I2C Master and Slave
+ IntDefaultHandler, // PWM Fault
+ IntDefaultHandler, // PWM Generator 0
+ IntDefaultHandler, // PWM Generator 1
+ IntDefaultHandler, // PWM Generator 2
+ IntDefaultHandler, // Quadrature Encoder
+ IntDefaultHandler, // ADC Sequence 0
+ IntDefaultHandler, // ADC Sequence 1
+ IntDefaultHandler, // ADC Sequence 2
+ IntDefaultHandler, // ADC Sequence 3
+ IntDefaultHandler, // Watchdog timer
+ IntDefaultHandler, // Timer 0 subtimer A
+ IntDefaultHandler, // Timer 0 subtimer B
+ IntDefaultHandler, // Timer 1 subtimer A
+ IntDefaultHandler, // Timer 1 subtimer B
+ IntDefaultHandler, // Timer 2 subtimer A
+ IntDefaultHandler, // Timer 2 subtimer B
+ IntDefaultHandler, // Analog Comparator 0
+ IntDefaultHandler, // Analog Comparator 1
+ IntDefaultHandler, // Analog Comparator 2
+ IntDefaultHandler, // System Control (PLL, OSC, BO)
+ IntDefaultHandler, // FLASH Control
+ IntDefaultHandler, // GPIO Port F
+ IntDefaultHandler, // GPIO Port G
+ IntDefaultHandler, // GPIO Port H
+ IntDefaultHandler, // UART2 Rx and Tx
+ IntDefaultHandler, // SSI1 Rx and Tx
+ IntDefaultHandler, // Timer 3 subtimer A
+ IntDefaultHandler, // Timer 3 subtimer B
+ IntDefaultHandler, // I2C1 Master and Slave
+ IntDefaultHandler, // Quadrature Encoder 1
+ IntDefaultHandler, // CAN0
+ IntDefaultHandler, // CAN1
+ IntDefaultHandler, // CAN2
+ IntDefaultHandler, // Ethernet
+ IntDefaultHandler, // Hibernate
+ IntDefaultHandler, // USB0
+ IntDefaultHandler, // PWM Generator 3
+ IntDefaultHandler, // uDMA Software Transfer
+ IntDefaultHandler // uDMA Error
+};
+
+//*****************************************************************************
+//
+// The following are constructs created by the linker, indicating where the
+// the "data" and "bss" segments reside in memory. The initializers for the
+// for the "data" segment resides immediately following the "text" segment.
+//
+//*****************************************************************************
+extern unsigned long _etext;
+extern unsigned long _sdata;
+extern unsigned long _edata;
+extern unsigned long _sbss;
+extern unsigned long _ebss;
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor first starts execution
+// following a reset event. Only the absolutely necessary set is performed,
+// after which the application supplied main() routine is called. Any fancy
+// actions (such as making decisions based on the reset cause register, and
+// resetting the bits in that register) are left solely in the hands of the
+// application.
+//
+//*****************************************************************************
+void
+ResetISR(void)
+{
+ unsigned long *pulSrc, *pulDest;
+
+ //
+ // Copy the data segment initializers from flash to SRAM.
+ //
+ pulSrc = &_etext;
+ for(pulDest = &_sdata; pulDest < &_edata; )
+ {
+ *pulDest++ = *pulSrc++;
+ }
+
+ //
+ // Zero fill the bss segment. This is done with inline assembly since this
+ // will clear the value of pulDest if it is not kept in a register.
+ //
+ __asm(" ldr r0, =_sbss\n"
+ " ldr r1, =_ebss\n"
+ " mov r2, #0\n"
+ " .thumb_func\n"
+ "zero_loop:\n"
+ " cmp r0, r1\n"
+ " it lt\n"
+ " strlt r2, [r0], #4\n"
+ " blt zero_loop");
+
+ //
+ // Call the application's entry point.
+ //
+ main();
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a NMI. This
+// simply enters an infinite loop, preserving the system state for examination
+// by a debugger.
+//
+//*****************************************************************************
+static void
+NmiSR(void)
+{
+ //
+ // Enter an infinite loop.
+ //
+ while(1)
+ {
+ }
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives a fault
+// interrupt. This simply enters an infinite loop, preserving the system state
+// for examination by a debugger.
+//
+//*****************************************************************************
+static void
+FaultISR(void)
+{
+ //
+ // Enter an infinite loop.
+ //
+ while(1)
+ {
+ }
+}
+
+//*****************************************************************************
+//
+// This is the code that gets called when the processor receives an unexpected
+// interrupt. This simply enters an infinite loop, preserving the system state
+// for examination by a debugger.
+//
+//*****************************************************************************
+static void
+IntDefaultHandler(void)
+{
+ //
+ // Go into an infinite loop.
+ //
+ while(1)
+ {
+ }
+}