git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@606 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-01-10 14:56:02 +00:00
parent 078651da50
commit ea60d55415
8 changed files with 141 additions and 348 deletions

View File

@ -84,7 +84,7 @@ ASRC = ../../ports/ARM7-LPC214x/chcore.c \
TSRC =
# List ASM source files here
ASMSRC = ../../ports/ARM7/crt0.s ../../ports/ARM7/chsys.s \
ASMSRC = ../../ports/ARM7/crt0.s ../../ports/ARM7/chsysasm.s \
../../ports/ARM7-LPC214x/vectors.s
# List all user directories here

View File

@ -17,38 +17,51 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup ARM7_CORE
* @{
*/
#include <ch.h>
#include "at91lib/AT91SAM7X256.h"
/*
* System idle thread loop.
* This file is a template of the system driver functions provided by a port.
* Some of the following functions may be implemented as macros in chcore.h if
* the implementer decides that there is an advantage in doing so, as example
* because performance concerns.
*/
void _idle(void *p) {
/**
* Prints a message on the system console.
* @param msg pointer to the message
*/
__attribute__((weak))
void sys_puts(char *msg) {
}
/**
* Enters an architecture-dependent halt mode. The function is meant to return
* when an interrupt becomes pending.
*/
__attribute__((weak))
void sys_wait_for_interrupt(void) {
PCON = 1;
}
/**
* Halts the system. This function is invoked by the operating system when an
* unrecoverable error is detected (as example because a programming error in
* the application code that triggers an assertion while in debug mode).
*/
__attribute__((weak))
void sys_halt(void) {
sys_disable_all();
while (TRUE) {
// Note, it is disabled because it causes trouble with the JTAG probe.
// Enable it in the final code only.
// PCON = 1;
}
}
/*
* System console message (not implemented).
*/
void chSysPuts(char *msg) {
}
/*
* System halt.
*/
__attribute__((naked, weak))
void chSysHalt(void) {
#ifdef THUMB
asm volatile ("ldr r0, =_halt16");
asm volatile ("bx r0");
#else
asm("b _halt32");
#endif
}
/** @} */

View File

@ -17,38 +17,51 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup ARM7_CORE
* @{
*/
#include <ch.h>
#include "lpc214x.h"
/*
* System idle thread loop.
* This file is a template of the system driver functions provided by a port.
* Some of the following functions may be implemented as macros in chcore.h if
* the implementer decides that there is an advantage in doing so, as example
* because performance concerns.
*/
void _idle(void *p) {
/**
* Prints a message on the system console.
* @param msg pointer to the message
*/
__attribute__((weak))
void sys_puts(char *msg) {
}
/**
* Enters an architecture-dependent halt mode. The function is meant to return
* when an interrupt becomes pending.
*/
__attribute__((weak))
void sys_wait_for_interrupt(void) {
PCON = 1;
}
/**
* Halts the system. This function is invoked by the operating system when an
* unrecoverable error is detected (as example because a programming error in
* the application code that triggers an assertion while in debug mode).
*/
__attribute__((weak))
void sys_halt(void) {
sys_disable_all();
while (TRUE) {
// Note, it is disabled because it causes trouble with the JTAG probe.
// Enable it in the final code only.
// PCON = 1;
}
}
/*
* System console message (not implemented).
*/
void chSysPuts(char *msg) {
}
/*
* System halt.
*/
__attribute__((naked, weak))
void chSysHalt(void) {
#ifdef THUMB
asm volatile ("ldr r0, =_halt16");
asm volatile ("bx r0");
#else
asm volatile ("b _halt32");
#endif
}
/** @} */

View File

@ -92,7 +92,7 @@ typedef struct {
sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = pf; \
tp->p_ctx.r13->r5 = arg; \
tp->p_ctx.r13->lr = threadstart; \
tp->p_ctx.r13->lr = _sys_thread_start; \
}
/**
@ -159,12 +159,12 @@ typedef struct {
*/
#ifdef THUMB
#define SYS_IRQ_EPILOGUE() { \
asm volatile ("ldr r0, =IrqCommon \n\t" \
asm volatile ("ldr r0, =_sys_irq_common \n\t" \
"bx r0"); \
}
#else /* THUMB */
#define SYS_IRQ_EPILOGUE() { \
asm volatile ("b IrqCommon"); \
asm volatile ("b _sys_irq_common"); \
}
#endif /* !THUMB */
@ -194,9 +194,9 @@ typedef struct {
* @note This macro assumes to be invoked in ARM system mode.
*/
#ifdef THUMB
#define sys_disable() asm volatile ("msr CPSR_c, #0x9F")
#else /* THUMB */
#define sys_disable() _sys_disable_thumb()
#else /* THUMB */
#define sys_disable() asm volatile ("msr CPSR_c, #0x9F")
#endif /* !THUMB */
/**
@ -206,9 +206,9 @@ typedef struct {
* @note This macro assumes to be invoked in ARM system mode.
*/
#ifdef THUMB
#define sys_enable() asm volatile ("msr CPSR_c, #0x1F")
#else /* THUMB */
#define sys_enable() _sys_enable_thumb()
#else /* THUMB */
#define sys_enable() asm volatile ("msr CPSR_c, #0x1F")
#endif /* !THUMB */
/**
@ -221,6 +221,23 @@ typedef struct {
*/
#define sys_enable_from_isr()
/**
* Disables all the interrupt sources, even those having a priority higher
* to the kernel.
* In the ARM7 port this code disables both IRQ and FIQ sources.
*/
#ifdef THUMB
#define sys_disable_all() _sys_disable_all_thumb()
#else /* THUMB */
#define sys_disable_all() { \
asm volatile ("mrs r3, CPSR \n\t" \
"orr r3, #0x80 \n\t" \
"msr CPSR_c, r3 \n\t" \
"orr r3, #0x40 \n\t" \
"msr CPSR_c, r3" : : : "r3"); \
}
#endif /* !THUMB */
#ifdef __cplusplus
extern "C" {
#endif
@ -234,6 +251,7 @@ extern "C" {
#else /* THUMB */
void _sys_switch_arm(Thread *otp, Thread *ntp);
#endif /* !THUMB */
void _sys_thread_start(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,237 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* ARM7 port system code.
*/
#include <chconf.h>
.set MODE_USR, 0x10
.set MODE_FIQ, 0x11
.set MODE_IRQ, 0x12
.set MODE_SVC, 0x13
.set MODE_ABT, 0x17
.set MODE_UND, 0x1B
.set MODE_SYS, 0x1F
.equ I_BIT, 0x80
.equ F_BIT, 0x40
.text
/*
* Interrupt enable/disable functions, only present if there is THUMB code in
* the system because those are inlined in ARM code.
*/
#ifdef THUMB_PRESENT
.balign 16
.code 16
.thumb_func
.global _lock
_lock:
mov r0, pc
bx r0
.code 32
mrs r0, CPSR
msr CPSR_c, #MODE_SYS | I_BIT
bx lr
.balign 16
.code 16
.thumb_func
.global _unlock
_unlock:
mov r1, pc
bx r1
.code 32
msr CPSR_c, r0
bx lr
.balign 16
.code 16
.thumb_func
.global _enable
_enable:
mov r0, pc
bx r0
.code 32
msr CPSR_c, #MODE_SYS
bx lr
#endif
.balign 16
#ifdef THUMB_PRESENT
.code 16
.thumb_func
.global chSysSwitchI_thumb
chSysSwitchI_thumb:
mov r2, pc
bx r2
// Jumps into chSysSwitchI in ARM mode
#endif
.code 32
.global chSysSwitchI_arm
chSysSwitchI_arm:
#ifdef CH_CURRP_REGISTER_CACHE
stmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr}
str sp, [r0, #16]
ldr sp, [r1, #16]
#ifdef THUMB_PRESENT
ldmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr}
bx lr
#else /* !THUMB_PRESENT */
ldmfd sp!, {r4, r5, r6, r8, r9, r10, r11, pc}
#endif /* !THUMB_PRESENT */
#else /* !CH_CURRP_REGISTER_CACHE */
stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
str sp, [r0, #16]
ldr sp, [r1, #16]
#ifdef THUMB_PRESENT
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
bx lr
#else /* !THUMB_PRESENT */
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
#endif /* !THUMB_PRESENT */
#endif /* !CH_CURRP_REGISTER_CACHE */
/*
* Common exit point for all IRQ routines, it performs the rescheduling if
* required.
* System stack frame structure after a context switch in the
* interrupt handler:
*
* High +------------+
* | LR_USR | -+
* | R12 | |
* | R3 | |
* | R2 | | External context: IRQ handler frame
* | R1 | |
* | R0 | |
* | PC | | (user code return address)
* | PSR_USR | -+ (user code status)
* | .... | <- mk_DoRescheduleI() stack frame, optimize it for space
* | LR | -+ (system code return address)
* | R11 | |
* | R10 | |
* | R9 | |
* | R8 | | Internal context: mk_SwitchI() frame
* | (R7) | | (optional, see CH_CURRP_REGISTER_CACHE)
* | R6 | |
* | R5 | |
* SP-> | R4 | -+
* Low +------------+
*/
.balign 16
#ifdef THUMB_NO_INTERWORKING
.code 16
.thumb_func
.globl IrqCommon
IrqCommon:
bl chSchRescRequiredI
mov lr, pc
bx lr
.code 32
#else /* !THUMB_NO_INTERWORKING */
.code 32
.globl IrqCommon
IrqCommon:
bl chSchRescRequiredI
#endif /* !THUMB_NO_INTERWORKING */
cmp r0, #0 // Simply returns if a
ldmeqfd sp!, {r0-r3, r12, lr} // reschedule is not
subeqs pc, lr, #4 // required.
// Saves the IRQ mode registers in the system stack.
ldmfd sp!, {r0-r3, r12, lr} // IRQ stack now empty.
msr CPSR_c, #MODE_SYS | I_BIT
stmfd sp!, {r0-r3, r12, lr} // Registers on System Stack.
msr CPSR_c, #MODE_IRQ | I_BIT
mrs r0, SPSR
mov r1, lr
msr CPSR_c, #MODE_SYS | I_BIT
stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
// Context switch.
#ifdef THUMB_NO_INTERWORKING
add r0, pc, #1
bx r0
.code 16
bl chSchDoRescheduleI
mov lr, pc
bx lr
.code 32
#else /* !THUMB_NO_INTERWORKING */
bl chSchDoRescheduleI
#endif /* !THUMB_NO_INTERWORKING */
// Re-establish the IRQ conditions again.
ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
msr CPSR_c, #MODE_IRQ | I_BIT
msr SPSR_fsxc, r0
mov lr, r1
msr CPSR_c, #MODE_SYS | I_BIT
ldmfd sp!, {r0-r3, r12, lr}
msr CPSR_c, #MODE_IRQ | I_BIT
subs pc, lr, #4
/*
* Threads trampoline code.
* NOTE: The threads always start in ARM mode then switch to the thread-function mode.
*/
.balign 16
.code 32
.globl threadstart
threadstart:
msr CPSR_c, #MODE_SYS
#ifndef THUMB_NO_INTERWORKING
mov r0, r5
mov lr, pc
bx r4
bl chThdExit
#else /* !THUMB_NO_INTERWORKING */
add r0, pc, #1
bx r0
.code 16
mov r0, r5
bl jmpr4
bl chThdExit
jmpr4:
bx r4
#endif /* !THUMB_NO_INTERWORKING */
/*
* System stop code.
*/
.code 16
.p2align 2,,
.thumb_func
.weak _halt16
.globl _halt16
_halt16:
mov r0, pc
bx r0
.code 32
.weak _halt32
.globl _halt32
_halt32:
mrs r0, CPSR
orr r0, #I_BIT | F_BIT
msr CPSR_c, r0
.loop: b .loop

View File

@ -44,35 +44,38 @@
.balign 16
.code 16
.thumb_func
.global _lock
_lock:
.global _sys_disable_thumb
_sys_disable_thumb:
mov r0, pc
bx r0
.code 32
mrs r0, CPSR
msr CPSR_c, #MODE_SYS | I_BIT
bx lr
.balign 16
.code 16
.thumb_func
.global _unlock
_unlock:
mov r1, pc
bx r1
.global _sys_enable_thumb
_sys_enable_thumb:
mov r0, pc
bx r0
.code 32
msr CPSR_c, r0
msr CPSR_c, #MODE_SYS
bx lr
.balign 16
.code 16
.thumb_func
.global _enable
_enable:
.global _sys_disable_all_thumb
_sys_disable_all_thumb:
mov r0, pc
bx r0
.code 32
msr CPSR_c, #MODE_SYS
mrs r0, CPSR
orr r0, #I_BIT
msr CPSR_c, r0
orr r0, #F_BIT
msr CPSR_c, r0
bx lr
#endif
@ -80,15 +83,15 @@ _enable:
#ifdef THUMB_PRESENT
.code 16
.thumb_func
.global chSysSwitchI_thumb
chSysSwitchI_thumb:
.global _sys_switch_thumb
_sys_switch_thumb:
mov r2, pc
bx r2
// Jumps into chSysSwitchI in ARM mode
// Jumps into _sys_switch_arm in ARM mode
#endif
.code 32
.global chSysSwitchI_arm
chSysSwitchI_arm:
.global _sys_switch_arm
_sys_switch_arm:
#ifdef CH_CURRP_REGISTER_CACHE
stmfd sp!, {r4, r5, r6, r8, r9, r10, r11, lr}
str sp, [r0, #16]
@ -142,16 +145,16 @@ chSysSwitchI_arm:
#ifdef THUMB_NO_INTERWORKING
.code 16
.thumb_func
.globl IrqCommon
IrqCommon:
.globl _sys_irq_common
_sys_irq_common:
bl chSchRescRequiredI
mov lr, pc
bx lr
.code 32
#else /* !THUMB_NO_INTERWORKING */
.code 32
.globl IrqCommon
IrqCommon:
.globl _sys_irq_common
_sys_irq_common:
bl chSchRescRequiredI
#endif /* !THUMB_NO_INTERWORKING */
cmp r0, #0 // Simply returns if a
@ -197,8 +200,8 @@ IrqCommon:
*/
.balign 16
.code 32
.globl threadstart
threadstart:
.globl _sys_thread_start
_sys_thread_start:
msr CPSR_c, #MODE_SYS
#ifndef THUMB_NO_INTERWORKING
mov r0, r5
@ -215,23 +218,3 @@ threadstart:
jmpr4:
bx r4
#endif /* !THUMB_NO_INTERWORKING */
/*
* System stop code.
*/
.code 16
.p2align 2,,
.thumb_func
.weak _halt16
.globl _halt16
_halt16:
mov r0, pc
bx r0
.code 32
.weak _halt32
.globl _halt32
_halt32:
mrs r0, CPSR
orr r0, #I_BIT | F_BIT
msr CPSR_c, r0
.loop: b .loop

View File

@ -94,16 +94,6 @@ void chSysTimerHandlerI(void) {
chVTDoTickI();
}
/**
* Abonormal system termination handler. Invoked by the ChibiOS/RT when an
* abnormal unrecoverable condition is met.
*/
void chSysHalt(void) {
chSysDisable();
sys_halt();
}
#if !defined(CH_OPTIMIZE_SPEED)
/**
* Enters the ChibiOS/RT system mutual exclusion zone.

View File

@ -31,6 +31,12 @@
*/
#define chSysPuts(msg) sys_puts(msg)
/**
* Abonormal system termination handler. Invoked by the ChibiOS/RT when an
* abnormal unrecoverable condition is met.
*/
#define chSysHalt() sys_halt()
/**
* Performs a context switch.
* This is the most critical code in any port, this function is responsible
@ -52,8 +58,8 @@
#define chSysEnable() sys_enable()
/**
* Raises the system interrupt priority mask to system level.
* @note The implementation is architecture dependent, it may just enable the
* Raises the system interrupt priority mask to system level.
* @note The implementation is architecture dependent, it may just disable the
* interrupts.
* @note This API should only be invoked from the main thread in order to stop
* ChibiOS/RT, hardware de/re-initialization should follow. It would then
@ -62,6 +68,14 @@
*/
#define chSysDisable() sys_disable()
/**
* Raises the system interrupt priority mask to the maximum level thus disabling
* any mask-able interrupt source..
* @note The implementation is architecture dependent, it may just disable the
* interrupts or be exactly equivalent to @p chSysDisable().
*/
#define chSysDisableAll() sys_disable_all()
/**
* Enters the ChibiOS/RT system mutual exclusion zone from within an interrupt
* handler.
@ -161,7 +175,6 @@ extern "C" {
#endif
void chSysInit(void);
void chSysTimerHandlerI(void);
void chSysHalt(void);
#if !defined(CH_OPTIMIZE_SPEED)
void chSysLock(void);
void chSysUnlock(void);