908df725ad
reason: 1 On different architectures, we can utilize more optimized strategies to implement up_current_regs/up_set_current_regs. eg. use interrupt registersor percpu registers. code size before text data bss dec hex filename 262848 49985 63893 376726 5bf96 nuttx after text data bss dec hex filename 262844 49985 63893 376722 5bf92 nuttx size change -4 Configuring NuttX and compile: $ ./tools/configure.sh -l qemu-armv8a:nsh_smp $ make Running with qemu $ qemu-system-aarch64 -cpu cortex-a53 -smp 4 -nographic \ -machine virt,virtualization=on,gic-version=3 \ -net none -chardev stdio,id=con,mux=on -serial chardev:con \ -mon chardev=con,mode=readline -kernel ./nuttx Signed-off-by: hujun5 <hujun5@xiaomi.com>
181 lines
5.2 KiB
C
181 lines
5.2 KiB
C
/****************************************************************************
|
|
* arch/sim/include/irq.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* This file should never be included directly but, rather,
|
|
* only indirectly through nuttx/irq.h
|
|
*/
|
|
|
|
#ifndef __ARCH_SIM_INCLUDE_IRQ_H
|
|
#define __ARCH_SIM_INCLUDE_IRQ_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <arch/setjmp.h>
|
|
#include <sys/types.h>
|
|
#ifndef __ASSEMBLY__
|
|
# include <stdbool.h>
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#define NR_IRQS 64
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
/* This struct defines the way the registers are stored */
|
|
|
|
struct xcptcontext
|
|
{
|
|
void *sigdeliver; /* Actual type is sig_deliver_t */
|
|
jmp_buf regs;
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
#define EXTERN extern "C"
|
|
extern "C"
|
|
{
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Public Data
|
|
****************************************************************************/
|
|
|
|
/* g_current_regs[] holds a references to the current interrupt level
|
|
* register storage structure. If is non-NULL only during interrupt
|
|
* processing. Access to g_current_regs[] must be through the
|
|
* [get/set]_current_regs for portability.
|
|
*/
|
|
|
|
/* For the case of architectures with multiple CPUs, then there must be one
|
|
* such value for each processor that can receive an interrupt.
|
|
*/
|
|
|
|
EXTERN volatile xcpt_reg_t *g_current_regs[CONFIG_SMP_NCPUS];
|
|
|
|
/****************************************************************************
|
|
* Public Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_cpu_index
|
|
*
|
|
* Description:
|
|
* Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
|
|
* corresponds to the currently executing CPU.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
|
|
* corresponds to the currently executing CPU.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SMP
|
|
int up_cpu_index(void);
|
|
#else
|
|
# define up_cpu_index() (0)
|
|
#endif
|
|
|
|
/* Name: up_irq_save, up_irq_restore, and friends.
|
|
*
|
|
* NOTE: These functions should never be called from application code and,
|
|
* as a general rule unless you really know what you are doing, this
|
|
* function should not be called directly from operation system code either:
|
|
* Typically, the wrapper functions, enter_critical_section() and
|
|
* leave_critical section(), are probably what you really want.
|
|
*/
|
|
|
|
irqstate_t up_irq_flags(void);
|
|
irqstate_t up_irq_save(void);
|
|
void up_irq_restore(irqstate_t flags);
|
|
void up_irq_enable(void);
|
|
|
|
/****************************************************************************
|
|
* Inline functions
|
|
****************************************************************************/
|
|
|
|
static inline_function xcpt_reg_t *up_current_regs(void)
|
|
{
|
|
return (xcpt_reg_t *)g_current_regs[up_cpu_index()];
|
|
}
|
|
|
|
static inline_function void up_set_current_regs(xcpt_reg_t *regs)
|
|
{
|
|
g_current_regs[up_cpu_index()] = regs;
|
|
}
|
|
|
|
/* Return the current value of the stack pointer */
|
|
|
|
static inline uintptr_t up_getsp(void)
|
|
{
|
|
#ifdef _MSC_VER
|
|
uintptr_t regval;
|
|
__asm mov regval, esp;
|
|
return regval;
|
|
#else
|
|
return (uintptr_t)__builtin_frame_address(0);
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Name: up_interrupt_context
|
|
*
|
|
* Description:
|
|
* Return true is we are currently executing in the interrupt
|
|
* handler context.
|
|
*
|
|
****************************************************************************/
|
|
|
|
noinstrument_function
|
|
static inline bool up_interrupt_context(void)
|
|
{
|
|
#ifdef CONFIG_SMP
|
|
irqstate_t flags = up_irq_save();
|
|
#endif
|
|
|
|
bool ret = up_current_regs() != NULL;
|
|
|
|
#ifdef CONFIG_SMP
|
|
up_irq_restore(flags);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
#undef EXTERN
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
#endif /* __ARCH_SIM_INCLUDE_IRQ_H */
|