📄 cpu_config.h
字号:
/*
* The above copyright holder, limited to cases in which one satisfies
* conditions (1) ~ (4) below, or the conditions described in Version 2
* of of the GNU Public License officially announced by the Free Software
* Foundation, consents to the use, reproduction, alteration, and
* redistribution (hereafter called utilization) of this software (this
* software includes alterations, likewise below) without compensation.
*
* (1) When this software is utilized in the form of source code, the
* above copyright declaration, these conditions of utilization, and the
* following stipulation of no guarantee shall be included in unchanged
* form inside the source code.
* (2) When this software is redistributed in a form in which it can be
* used in the development of other software, library form, etc., the above
* copyright display, these terms of utilization, and the following
* stipulation of no guarantee shall be inserted in documentation accompanying
* redistribution (user's manual, etc.).
* (3) When this software is redistributed in a form in which it cannot be used
* in the development of other software, embedded in devices, etc., one of the
* following conditions shall be satisfied.
* (a) The above copyright display, these terms of utilization, and the
* following stipulation of no guarantee shall be inserted in documentation
* accompanying redistribution (user's manual, etc.).
* (b) The TOPPERS Project shall be notified owing to a method in which the
* form of distribution is decided otherwise.
* (4) The above copyright holder and the TOPPERS Project shall be exempt
* from responsibility for whatever damages occur either directly or indirectly
* through the utilization of this software.
*
* This software is something that is provided with no guarantee. The above copyright
* holder and the TOPPERS Project make no guarantee whatsoever in regard to this
* software, including the possibility of its application. In addition, the above
* copyright holder and the TOPPERS Project shall also not bear responsibility for
* whatever damages occur either directly or indirectly through the utilization of
* this software.
*
* @(#) $Id: cpu_config.h,v 1.3 2006/08/10 08:11:37 0684248 Exp $
*/
/*
* Module that dependent to the processor (for the use of ARM4vT)
*
* As for this include file, include is done only from t_config.h.
* Do not do include directly from other files.
*/
#ifndef _CPU_CONFIG_H_
#define _CPU_CONFIG_H_
/*
* Rename the internal identifiers of kernel
*/
#include "cpu_rename.h"
/*
* Define in-line function of special instruction of processor
*/
#ifndef _MACRO_ONLY
#include <cpu_insn.h>
#endif /* _MACRO_ONLY */
/*
* Definition related to TCB
*
* Though putting the dependency of the reference in cpu_context.h is more elegant,
* It is not put in cpu_context.h.
*/
/*
* Definition of width of bit in TCB field
*/
#define TBIT_TCB_TSTAT 8 /* Width of bit of tstat field */
#define TBIT_TCB_PRIORITY 8 /* Width of bit of priority field */
#ifndef _MACRO_ONLY
/*
* Definition of task context block
*/
typedef struct task_context_block {
VP sp; /* Stack pointer */
FP pc; /* Program counter */
} CTXB;
/*
* Counter of nest times of the interruptions
*/
extern UW interrupt_count;
/*
* System state reference
*/
Inline UB
current_mode()
{
return(current_sr() & CPSR_MODE_MASK);
}
Inline BOOL
sense_context()
{
return(interrupt_count > 0);
}
Inline BOOL
sense_lock()
{
return(current_sr() & CPSR_IRQ_BIT);
}
#define t_sense_lock sense_lock
#define i_sense_lock sense_lock
/*
* CPU Lock and unlock
*
*/
#define t_lock_cpu lock_cpu
#define i_lock_cpu lock_cpu
#define t_unlock_cpu unlock_cpu
#define i_unlock_cpu unlock_cpu
Inline void
lock_cpu()
{
disint();
}
Inline void
unlock_cpu()
{
enaint();
}
/*
* Task Dispatcher
*/
/*
* Dispatch in the task with the highest priority level(cpu_support.S)
*
* Dispatch is called from task context. While the service call is processing,
* it is necessary to call it under the state of CPU locked.
*/
extern void dispatch(void);
/*
* The present context is thrown away and dispatches it. (cpu_support.S)
*
* It is necessary to call exit_and_dispatch under the state of CPU locked.
*/
extern void exit_and_dispatch(void);
/*
* The reference address to the jump instruction that already had been written in exception vector
*/
extern UW * arm_vector_add[8];
/*
* Start address number of the handler that corresponding to exception
*/
extern UW arm_handler_add[8];
/*
* Set the handler of CPU exceptions
*/
extern void define_exc(EXCNO excno, FP exchdr);
Inline void
arm_install_handler(EXCNO excno, FP exchdr)
{
*arm_vector_add[excno] = (UW)exchdr;
}
/*
* Gateway processing of CPU exception handler
*/
/*
* The macro used to generate the gateway processing of CPU exception handler
*
*/
#define __EXCHDR_ENTRY(exchdr, stacktop) \
extern void exchdr##_entry(VP sp); \
asm(".text \n" \
#exchdr "_entry: \n" \
" ldr sp,.int_stack_"#exchdr" \n" /* Switch of stack */\
" sub lr,lr,#4 \n" /* Is it good enouth to undef it here? */\
" stmfd sp!, {r0 - r2,lr} \n" /* It saves to int_stack temporarily. */ \
" mrs r1, spsr \n" /* For switching to the SVC mode */ \
" mov r0, sp \n" /* Save */ \
" mov r2,#0xd3 \n" /* Rewriting of CPSR(To the SVC mode. ) */ \
" msr cpsr,r2 \n" \
" ldr r2,[r0,#0x0C] \n" /* load PC */\
" stmfd sp!,{r2} \n" /* Store PC */\
" stmfd sp!,{r3,ip,lr} \n" /* Store r3,ip,lr */\
" ldmfd r0!,{r2,ip,lr} \n" /* load r0,r1,r2 */\
" stmfd sp!,{r1,r2,ip,lr} \n" /* SPSR,Store r0,r1,r2 */\
" ldr r2, .interrupt_count_"#exchdr"\n" /* Check if it is multiple interruptions */\
" ldr r3, [r2] \n" \
" add r0,r3,#1 \n" \
" str r0, [r2] \n" \
" mov r0,sp \n" /* Parameter to the exception handler */\
" cmp r3, #0x00 \n" \
" ldreq sp,stack_"#exchdr" \n" /* the modification of task */\
" stmeqfd sp!,{r0} \n" /* Save the stack of the task */\
" and r2, r1, #0xc0 \n" /* When exception occured, the lock state of the CPU(IRQ) */\
" orr r2, r2, #0x13 \n" /* and inherit from FIQ. SVC mode */\
" msr cpsr,r2 \n" \
" bl "#exchdr" \n" /* Handler call */\
" mrs r2, cpsr \n" /* inherit from FIQ */\
" and r2, r2, #0x40 \n" /* */\
" orr r2, r2, #0x93 \n" /* Disable the interrupt */\
" msr cpsr,r2 \n" \
" ldr r2,.interrupt_count_"#exchdr" \n"/* Decrement of Interrupt number */\
" ldr r1, [r2] \n" /* Decrement */\
" sub r3,r1,#1 \n"\
" str r3, [r2] \n"\
" cmp r3,#0x00 \n" /* Nest number of interrupt */\
" bne return_to_task_"#exchdr" \n" \
" ldmfd sp!,{r0} \n" /* Resume the task stack */\
" mov sp, r0 \n"\
" ldr r1, reqflg_"#exchdr" \n" /* Check reqflg */\
" ldr r0,[r1] \n"\
" cmp r0,#0 \n"\
" beq return_to_task_"#exchdr" \n"\
" mov r0,#0 \n"\
" str r0,[r1] \n" /* Clear reqflg */\
" b _kernel_ret_exc \n" /* To ret_int */\
"return_to_task_"#exchdr": \n" \
" ldmfd sp!,{r1} \n" /* reset process of CPSR r1 <- cpsr */\
" mrs r2, cpsr \n" /* Inherit FIQ */\
" and r2, r2, #0x40 \n" /* */\
" and r1, r1, #~0x40 \n" /* */\
" orr r1, r1, r2 \n" /* */\
" msr spsr, r1 \n" /* Enable the interrupt */\
" ldmfd sp!,{r0-r3,ip,lr,pc}^ \n"\
" .align 4 \n"\
".int_stack_"#exchdr": \n"\
" .long _kernel_int_stack + 6 * 4 \n"\
"reqflg_"#exchdr": \n"\
" .long _kernel_reqflg \n"\
"stack_"#exchdr": \n"\
" .long " #stacktop " \n"\
".interrupt_count_"#exchdr": \n"\
" .long _kernel_interrupt_count \n")
#define _EXCHDR_ENTRY(exchdr, stacktop) __EXCHDR_ENTRY(exchdr, stacktop)
#define EXCHDR_ENTRY(exchdr) _EXCHDR_ENTRY(exchdr, STACKTOP)
#define EXC_ENTRY(exchdr) exchdr##_entry
/*
* Reference the system state when CPU exception occured
*/
/*
* Dispatch when CPU exception occured
*/
Inline BOOL
exc_sense_context(VP p_excinf)
{
return(interrupt_count > 1);
}
/*
* Reference the CPU lock state when CPU exception occured
*/
Inline BOOL
exc_sense_lock(VP p_excinf)
{
return((*((UW *)p_excinf) & CPSR_IRQ_BIT) == CPSR_IRQ_BIT );
}
/*
* When the undefined exception occured
*/
extern void undef_exception();
extern void swi_exception();
extern void prefetch_exception();
extern void data_abort_exception();
extern void irq_abort_exception();
extern void fiq_abort_exception();
/*
* Initialization of processor dependence
*/
extern void cpu_initialize(void);
/*
* Termination of processor dependence
*/
extern void cpu_terminate(void);
/*
* Stack temporarily used by the CPU/interruption handler's gateway processing
*/
#define INT_STACK_SIZE 6
extern UW int_stack[INT_STACK_SIZE];
#endif /* _MACRO_ONLY */
#endif /* _CPU_CONFIG_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -