2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2010-2014 Wind River Systems, Inc.
|
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* Licensed 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
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
2015-10-06 11:00:37 -05:00
|
|
|
* 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.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
|
2015-08-29 14:41:17 -04:00
|
|
|
/**
|
2015-07-15 17:10:25 -04:00
|
|
|
* @file
|
|
|
|
* @brief IA-32 specific nanokernel interface header
|
|
|
|
* This header contains the IA-32 specific nanokernel interface. It is included
|
|
|
|
* by the generic nanokernel interface header (nanokernel.h)
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifndef _ARCH_IFACE_H
|
|
|
|
#define _ARCH_IFACE_H
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
2015-06-01 16:18:34 -04:00
|
|
|
#include <arch/x86/asm_inline.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
2015-10-04 09:32:31 -04:00
|
|
|
/* APIs need to support non-byte addressable architectures */
|
2015-06-01 13:39:43 -04:00
|
|
|
|
|
|
|
#define OCTET_TO_SIZEOFUNIT(X) (X)
|
|
|
|
#define SIZEOFUNIT_TO_OCTET(X) (X)
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
2015-04-10 16:44:37 -07:00
|
|
|
* Macro used internally by NANO_CPU_INT_REGISTER and NANO_CPU_INT_REGISTER_ASM.
|
2015-07-27 09:47:56 -04:00
|
|
|
* Not meant to be used explicitly by platform, driver or application code.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
|
|
|
#define MK_ISR_NAME(x) __isr__##x
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
|
|
|
|
|
|
/* interrupt/exception/error related definitions */
|
|
|
|
|
|
|
|
#define _INT_STUB_SIZE 0x2b
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
2015-04-10 16:44:37 -07:00
|
|
|
* Performance optimization
|
|
|
|
*
|
|
|
|
* Macro PERF_OPT is defined if project is compiled with option other than
|
2015-05-20 10:33:48 -04:00
|
|
|
* size optimization ("-Os" for GCC, "-XO -Xsize-opt" for Diab). If the
|
2015-04-10 16:44:37 -07:00
|
|
|
* last of the compiler options is the size optimization, PERF_OPT is not
|
|
|
|
* defined and the project is optimized for size, hence the stub should be
|
|
|
|
* aligned to 1 and not 16.
|
|
|
|
*/
|
|
|
|
#ifdef PERF_OPT
|
|
|
|
#define _INT_STUB_ALIGN 16
|
|
|
|
#else
|
|
|
|
#define _INT_STUB_ALIGN 1
|
|
|
|
#endif
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
2015-05-26 10:21:42 -04:00
|
|
|
* Floating point register set alignment.
|
|
|
|
*
|
|
|
|
* If support for SSEx extensions is enabled a 16 byte boundary is required,
|
2015-10-04 10:01:56 -04:00
|
|
|
* since the 'fxsave' and 'fxrstor' instructions require this. In all other
|
2015-10-04 09:32:31 -04:00
|
|
|
* cases a 4 byte boundary is sufficient.
|
2015-05-26 10:21:42 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef CONFIG_SSE
|
|
|
|
#define FP_REG_SET_ALIGN 16
|
|
|
|
#else
|
|
|
|
#define FP_REG_SET_ALIGN 4
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
2015-08-20 11:04:01 -04:00
|
|
|
* The TCS must be aligned to the same boundary as that used by the floating
|
|
|
|
* point register set. This applies even for threads that don't initially
|
2015-05-26 10:21:42 -04:00
|
|
|
* use floating point, since it is possible to enable floating point support
|
|
|
|
* later on.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define STACK_ALIGN FP_REG_SET_ALIGN
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-26 10:21:42 -04:00
|
|
|
typedef unsigned char __aligned(_INT_STUB_ALIGN) NANO_INT_STUB[_INT_STUB_SIZE];
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-11 10:10:41 -05:00
|
|
|
typedef struct s_isrList {
|
2015-07-15 17:10:25 -04:00
|
|
|
/** Address of ISR/stub */
|
|
|
|
void *fnc;
|
2015-10-01 15:31:31 -04:00
|
|
|
/** IRQ associated with the ISR/stub */
|
|
|
|
unsigned int irq;
|
|
|
|
/** Priority associated with the IRQ */
|
|
|
|
unsigned int priority;
|
2015-07-15 17:10:25 -04:00
|
|
|
/** Vector number associated with ISR/stub */
|
|
|
|
unsigned int vec;
|
|
|
|
/** Privilege level associated with ISR/stub */
|
|
|
|
unsigned int dpl;
|
2015-04-10 16:44:37 -07:00
|
|
|
} ISR_LIST;
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Connect a routine to an interrupt vector
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-09-17 12:59:37 -04:00
|
|
|
* This macro "connects" the specified routine, @a r, to the specified interrupt
|
|
|
|
* vector, @a v using the descriptor privilege level @a d. On the IA-32
|
2015-07-01 17:22:39 -04:00
|
|
|
* architecture, an interrupt vector is a value from 0 to 255. This macro
|
|
|
|
* populates the special intList section with the address of the routine, the
|
|
|
|
* vector number and the descriptor privilege level. The genIdt tool then picks
|
|
|
|
* up this information and generates an actual IDT entry with this information
|
|
|
|
* properly encoded. This macro replaces the _IntVecSet () routine in static
|
|
|
|
* interrupt systems.
|
|
|
|
*
|
2015-09-17 12:59:37 -04:00
|
|
|
* The @a d argument specifies the privilege level for the interrupt-gate
|
2015-07-01 17:22:39 -04:00
|
|
|
* descriptor; (hardware) interrupts and exceptions should specify a level of 0,
|
|
|
|
* whereas handlers for user-mode software generated interrupts should specify 3.
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param r Routine to be connected
|
2015-10-01 15:31:31 -04:00
|
|
|
* @param n IRQ number
|
|
|
|
* @param p IRQ priority
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param v Interrupt Vector
|
|
|
|
* @param d Descriptor Privilege Level
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return N/A
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-10-01 15:31:31 -04:00
|
|
|
#define NANO_CPU_INT_REGISTER(r, n, p, v, d) \
|
|
|
|
ISR_LIST __attribute__((section(".intList"))) MK_ISR_NAME(r) = \
|
|
|
|
{&r, n, p, v, d}
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
/*
|
2015-07-15 17:10:25 -04:00
|
|
|
* @brief Declare a dynamic interrupt stub
|
|
|
|
*
|
2015-04-10 16:44:37 -07:00
|
|
|
* Macro to declare a dynamic interrupt stub. Using the macro places the stub
|
|
|
|
* in the .intStubSection which is located in the image according to the kernel
|
|
|
|
* configuration.
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param s Stub to be declared
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
2015-07-15 17:10:25 -04:00
|
|
|
#define NANO_CPU_INT_STUB_DECL(s) \
|
2015-05-12 10:43:08 -05:00
|
|
|
_NODATA_SECTION(.intStubSect) NANO_INT_STUB(s)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-06-01 14:14:31 -04:00
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Connect a routine to interrupt number
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
2015-09-17 12:59:37 -04:00
|
|
|
* For the device @a device associates IRQ number @a irq with priority
|
|
|
|
* @a priority with the interrupt routine @a isr, that receives parameter
|
2015-09-30 15:33:10 -04:00
|
|
|
* @a parameter.
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param device Device
|
2015-09-17 12:59:37 -04:00
|
|
|
* @param irq IRQ number
|
2015-09-30 15:33:10 -04:00
|
|
|
* @param priority IRQ Priority (currently ignored)
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param isr Interrupt Service Routine
|
|
|
|
* @param parameter ISR parameter
|
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return N/A
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
|
|
|
*/
|
2015-10-01 15:31:31 -04:00
|
|
|
#define IRQ_CONNECT_STATIC(device, irq, priority, isr, parameter) \
|
|
|
|
const uint32_t _##device##_int_vector = INT_VEC_IRQ0 + (irq); \
|
|
|
|
extern void *_##device##_##isr##_stub; \
|
|
|
|
NANO_CPU_INT_REGISTER(_##device##_##isr##_stub, (irq), (priority), \
|
|
|
|
INT_VEC_IRQ0 + (irq), 0)
|
2015-06-01 14:14:31 -04:00
|
|
|
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Configure interrupt for the device
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
2015-10-04 09:32:31 -04:00
|
|
|
* For the given device do the necessary configuration steps.
|
2015-06-01 14:14:31 -04:00
|
|
|
* For x86 platform configure APIC and mark interrupt vector allocated
|
2015-07-15 17:10:25 -04:00
|
|
|
* @param device Device
|
|
|
|
* @param irq IRQ
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return N/A
|
2015-06-01 14:14:31 -04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#define IRQ_CONFIG(device, irq) \
|
|
|
|
do { \
|
|
|
|
_SysIntVecProgram(_##device##_int_vector, irq); \
|
|
|
|
_IntVecMarkAllocated(_##device##_int_vector); \
|
2015-10-14 13:34:31 -07:00
|
|
|
} while (0)
|
2015-06-01 14:14:31 -04:00
|
|
|
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
|
|
|
* @brief Nanokernel Exception Stack Frame
|
2015-10-04 09:32:31 -04:00
|
|
|
*
|
2015-04-10 16:44:37 -07:00
|
|
|
* A pointer to an "exception stack frame" (ESF) is passed as an argument
|
|
|
|
* to exception handlers registered via nanoCpuExcConnect(). When an exception
|
|
|
|
* occurs while PL=0, then only the EIP, CS, and EFLAGS are pushed onto the stack.
|
|
|
|
* The least significant pair of bits in the CS value should be examined to
|
2015-08-13 16:55:03 -04:00
|
|
|
* determine whether the exception occurred while PL=3, in which case the ESP
|
|
|
|
* and SS values will also be present in the ESF. If the exception occurred
|
|
|
|
* while in PL=0, neither the SS nor ESP values will be present in the ESF.
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
|
|
|
* The exception stack frame includes the volatile registers EAX, ECX, and EDX
|
|
|
|
* pushed on the stack by _ExcEnt().
|
|
|
|
*
|
|
|
|
* It also contains the value of CR2, used when the exception is a page fault.
|
|
|
|
* Since that register is shared amongst threads of execution, it might get
|
|
|
|
* overwritten if another thread is context-switched in and then itself
|
|
|
|
* page-faults before the first thread has time to read CR2.
|
|
|
|
*
|
|
|
|
* If configured for host-based debug tools such as GDB, the 4 non-volatile
|
|
|
|
* registers (EDI, ESI, EBX, EBP) are also pushed by _ExcEnt()
|
|
|
|
* for use by the debug tools.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct nanoEsf {
|
2015-07-15 17:10:25 -04:00
|
|
|
/** putting cr2 here allows discarding it and pEsf in one instruction */
|
|
|
|
unsigned int cr2;
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef CONFIG_GDB_INFO
|
|
|
|
unsigned int ebp;
|
|
|
|
unsigned int ebx;
|
|
|
|
unsigned int esi;
|
|
|
|
unsigned int edi;
|
|
|
|
#endif /* CONFIG_GDB_INFO */
|
|
|
|
unsigned int edx;
|
|
|
|
unsigned int ecx;
|
|
|
|
unsigned int eax;
|
|
|
|
unsigned int errorCode;
|
|
|
|
unsigned int eip;
|
|
|
|
unsigned int cs;
|
|
|
|
unsigned int eflags;
|
|
|
|
unsigned int esp;
|
|
|
|
unsigned int ss;
|
|
|
|
} NANO_ESF;
|
|
|
|
|
2015-08-29 14:41:17 -04:00
|
|
|
/**
|
2015-07-15 17:10:25 -04:00
|
|
|
* @brief Nanokernel "interrupt stack frame" (ISF)
|
2015-10-04 09:32:31 -04:00
|
|
|
*
|
2015-04-10 16:44:37 -07:00
|
|
|
* An "interrupt stack frame" (ISF) as constructed by the processor
|
|
|
|
* and the interrupt wrapper function _IntExit(). When an interrupt
|
|
|
|
* occurs while PL=0, only the EIP, CS, and EFLAGS are pushed onto the stack.
|
|
|
|
* The least significant pair of bits in the CS value should be examined to
|
|
|
|
* determine whether the exception occurred while PL=3, in which case the ESP
|
|
|
|
* and SS values will also be present in the ESF. If the exception occurred
|
|
|
|
* while in PL=0, neither the SS nor ESP values will be present in the ISF.
|
|
|
|
*
|
|
|
|
* The interrupt stack frame includes the volatile registers EAX, ECX, and EDX
|
|
|
|
* pushed on the stack by _IntExit()..
|
|
|
|
*
|
|
|
|
* The host-based debug tools such as GDB do not require the 4 non-volatile
|
|
|
|
* registers (EDI, ESI, EBX, EBP) to be preserved during an interrupt.
|
|
|
|
* The register values saved/restored by _Swap() called from _IntExit() are
|
|
|
|
* sufficient.
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct nanoIsf {
|
|
|
|
unsigned int edx;
|
|
|
|
unsigned int ecx;
|
|
|
|
unsigned int eax;
|
|
|
|
unsigned int eip;
|
|
|
|
unsigned int cs;
|
|
|
|
unsigned int eflags;
|
|
|
|
unsigned int esp;
|
|
|
|
unsigned int ss;
|
|
|
|
} NANO_ISF;
|
|
|
|
|
|
|
|
#endif /* !_ASMLANGUAGE */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Reason codes passed to both _NanoFatalErrorHandler()
|
|
|
|
* and _SysFatalErrorHandler().
|
|
|
|
*/
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/** Unhandled exception/interrupt */
|
|
|
|
#define _NANO_ERR_SPURIOUS_INT (0)
|
|
|
|
/** Page fault */
|
|
|
|
#define _NANO_ERR_PAGE_FAULT (1)
|
|
|
|
/** General protection fault */
|
|
|
|
#define _NANO_ERR_GEN_PROT_FAULT (2)
|
|
|
|
/** Invalid task exit */
|
|
|
|
#define _NANO_ERR_INVALID_TASK_EXIT (3)
|
|
|
|
/** Stack corruption detected */
|
|
|
|
#define _NANO_ERR_STACK_CHK_FAIL (4)
|
|
|
|
/** Kernel Allocation Failure */
|
|
|
|
#define _NANO_ERR_ALLOCATION_FAIL (5)
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_NO_ISRS
|
|
|
|
|
2015-10-14 13:34:31 -07:00
|
|
|
static inline unsigned int irq_lock(void) { return 1; }
|
2015-04-10 16:44:37 -07:00
|
|
|
static inline void irq_unlock(unsigned int key) {}
|
|
|
|
|
|
|
|
#else /* CONFIG_NO_ISRS */
|
|
|
|
|
|
|
|
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
2015-05-12 10:12:36 -05:00
|
|
|
void _int_latency_start(void);
|
|
|
|
void _int_latency_stop(void);
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Disable all interrupts on the CPU (inline)
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
* This routine disables interrupts. It can be called from either interrupt,
|
|
|
|
* task or fiber level. This routine returns an architecture-dependent
|
|
|
|
* lock-out key representing the "interrupt disable state" prior to the call;
|
2015-08-12 18:31:41 -04:00
|
|
|
* this key can be passed to irq_unlock() to re-enable interrupts.
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-08-12 18:31:41 -04:00
|
|
|
* The lock-out key should only be used as the argument to the irq_unlock()
|
|
|
|
* API. It should never be used to manually re-enable interrupts or to inspect
|
|
|
|
* or manipulate the contents of the source register.
|
|
|
|
*
|
|
|
|
* This function can be called recursively: it will return a key to return the
|
|
|
|
* state of interrupt locking to the previous level.
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
* WARNINGS
|
|
|
|
* Invoking a kernel routine with interrupts locked may result in
|
|
|
|
* interrupts being re-enabled for an unspecified period of time. If the
|
|
|
|
* called routine blocks, interrupts will be re-enabled while another
|
2015-08-20 11:04:01 -04:00
|
|
|
* thread executes, or while the system is idle.
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-08-20 11:04:01 -04:00
|
|
|
* The "interrupt disable state" is an attribute of a thread. Thus, if a
|
2015-07-01 17:22:39 -04:00
|
|
|
* fiber or task disables interrupts and subsequently invokes a kernel
|
2015-08-20 11:04:01 -04:00
|
|
|
* routine that causes the calling thread to block, the interrupt
|
|
|
|
* disable state will be restored when the thread is later rescheduled
|
2015-07-01 17:22:39 -04:00
|
|
|
* for execution.
|
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return An architecture-dependent lock-out key representing the
|
2015-07-01 17:22:39 -04:00
|
|
|
* "interrupt disable state" prior to the call.
|
|
|
|
*
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-08-12 18:31:41 -04:00
|
|
|
static inline __attribute__((always_inline)) unsigned int irq_lock(void)
|
2015-05-14 16:30:48 -05:00
|
|
|
{
|
2015-08-12 18:31:41 -04:00
|
|
|
unsigned int key = _do_irq_lock();
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
2015-05-12 10:12:36 -05:00
|
|
|
_int_latency_start();
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return key;
|
2015-05-14 16:30:48 -05:00
|
|
|
}
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Enable all interrupts on the CPU (inline)
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-09-17 12:59:37 -04:00
|
|
|
* This routine re-enables interrupts on the CPU. The @a key parameter
|
2015-07-01 17:22:39 -04:00
|
|
|
* is an architecture-dependent lock-out key that is returned by a previous
|
2015-08-12 18:31:41 -04:00
|
|
|
* invocation of irq_lock().
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
* This routine can be called from either interrupt, task or fiber level.
|
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return N/A
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-08-12 18:31:41 -04:00
|
|
|
static inline __attribute__((always_inline)) void irq_unlock(unsigned int key)
|
2015-05-14 16:30:48 -05:00
|
|
|
{
|
|
|
|
if (!(key & 0x200)) {
|
2015-04-10 16:44:37 -07:00
|
|
|
return;
|
2015-05-14 16:30:48 -05:00
|
|
|
}
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef CONFIG_INT_LATENCY_BENCHMARK
|
2015-05-12 10:12:36 -05:00
|
|
|
_int_latency_stop();
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
2015-08-12 18:31:41 -04:00
|
|
|
_do_irq_unlock();
|
2015-04-10 16:44:37 -07:00
|
|
|
return;
|
2015-05-14 16:30:48 -05:00
|
|
|
}
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif /* CONFIG_NO_ISRS */
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/** interrupt/exception/error related definitions */
|
2015-04-10 16:44:37 -07:00
|
|
|
typedef void (*NANO_EOI_GET_FUNC) (void *);
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
2015-09-17 12:59:37 -04:00
|
|
|
* The NANO_SOFT_IRQ macro must be used as the value for the @a irq parameter
|
2015-04-10 16:44:37 -07:00
|
|
|
* to irq_connect() when connecting to a software generated interrupt.
|
|
|
|
*/
|
|
|
|
#define NANO_SOFT_IRQ ((unsigned int) (-1))
|
|
|
|
|
|
|
|
#ifdef CONFIG_FP_SHARING
|
2015-05-22 15:11:32 -04:00
|
|
|
/* Definitions for the 'options' parameter to the fiber_fiber_start() API */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-08-20 11:04:01 -04:00
|
|
|
/** thread uses floating point unit */
|
2015-07-15 17:10:25 -04:00
|
|
|
#define USE_FP 0x10
|
2015-04-10 16:44:37 -07:00
|
|
|
#ifdef CONFIG_SSE
|
2015-08-20 11:04:01 -04:00
|
|
|
/** thread uses SSEx instructions */
|
2015-07-15 17:10:25 -04:00
|
|
|
#define USE_SSE 0x20
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif /* CONFIG_SSE */
|
|
|
|
#endif /* CONFIG_FP_SHARING */
|
|
|
|
|
2015-05-12 10:12:36 -05:00
|
|
|
extern int irq_connect(unsigned int irq,
|
2015-04-10 16:44:37 -07:00
|
|
|
unsigned int priority,
|
2015-05-12 10:43:08 -05:00
|
|
|
void (*routine)(void *parameter),
|
2015-06-01 16:52:11 -04:00
|
|
|
void *parameter);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
|
|
|
* @brief Enable a specific IRQ
|
|
|
|
* @param irq IRQ
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
2015-05-12 10:12:36 -05:00
|
|
|
extern void irq_enable(unsigned int irq);
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
|
|
|
* @brief Disable a specific IRQ
|
|
|
|
* @param irq IRQ
|
|
|
|
*/
|
2015-05-12 10:12:36 -05:00
|
|
|
extern void irq_disable(unsigned int irq);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifdef CONFIG_FP_SHARING
|
2015-07-15 17:10:25 -04:00
|
|
|
/**
|
|
|
|
* @brief Enable floating point hardware resources sharing
|
2015-08-20 11:04:01 -04:00
|
|
|
* Dynamically enable/disable the capability of a thread to share floating
|
2015-04-10 16:44:37 -07:00
|
|
|
* point hardware resources. The same "floating point" options accepted by
|
2015-05-22 15:11:32 -04:00
|
|
|
* fiber_fiber_start() are accepted by these APIs (i.e. USE_FP and USE_SSE).
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
2015-08-20 11:04:01 -04:00
|
|
|
extern void fiber_float_enable(nano_thread_id_t thread_id,
|
|
|
|
unsigned int options);
|
|
|
|
extern void task_float_enable(nano_thread_id_t thread_id,
|
|
|
|
unsigned int options);
|
|
|
|
extern void fiber_float_disable(nano_thread_id_t thread_id);
|
|
|
|
extern void task_float_disable(nano_thread_id_t thread_id);
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif /* CONFIG_FP_SHARING */
|
|
|
|
|
|
|
|
#include <stddef.h> /* for size_t */
|
|
|
|
|
|
|
|
#ifdef CONFIG_NANOKERNEL
|
2015-05-12 10:12:36 -05:00
|
|
|
extern void nano_cpu_idle(void);
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
2015-07-15 17:10:25 -04:00
|
|
|
/** Nanokernel provided routine to report any detected fatal error. */
|
2015-04-10 16:44:37 -07:00
|
|
|
extern FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
|
2015-10-14 16:04:48 -07:00
|
|
|
const NANO_ESF *pEsf);
|
2015-07-15 17:10:25 -04:00
|
|
|
/** User provided routine to handle any detected fatal error post reporting. */
|
2015-04-10 16:44:37 -07:00
|
|
|
extern FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
2015-10-14 16:04:48 -07:00
|
|
|
const NANO_ESF *pEsf);
|
2015-07-15 17:10:25 -04:00
|
|
|
/** Dummy ESF for fatal errors that would otherwise not have an ESF */
|
2015-05-08 17:12:56 -05:00
|
|
|
extern const NANO_ESF _default_esf;
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-08-29 14:41:17 -04:00
|
|
|
/**
|
2015-07-15 17:10:25 -04:00
|
|
|
* @brief Configure an interrupt vector of the specified priority
|
|
|
|
*
|
2015-07-27 09:47:56 -04:00
|
|
|
* This routine is invoked by the kernel to configure an interrupt vector of
|
|
|
|
* the specified priority. To this end, it allocates an interrupt vector,
|
2015-10-04 09:32:31 -04:00
|
|
|
* programs hardware to route interrupt requests on the specified IRQ to that
|
2015-07-27 09:47:56 -04:00
|
|
|
* vector, and returns the vector number along with its associated BOI/EOI
|
|
|
|
* information.
|
2015-04-10 16:44:37 -07:00
|
|
|
*/
|
2015-07-15 17:10:25 -04:00
|
|
|
extern int _SysIntVecAlloc(unsigned int irq,
|
|
|
|
unsigned int priority,
|
|
|
|
NANO_EOI_GET_FUNC *boiRtn,
|
|
|
|
NANO_EOI_GET_FUNC *eoiRtn,
|
|
|
|
void **boiRtnParm,
|
|
|
|
void **eoiRtnParm,
|
|
|
|
unsigned char *boiParamRequired,
|
|
|
|
unsigned char *eoiParamRequired
|
|
|
|
);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-07-27 09:47:56 -04:00
|
|
|
/* functions provided by the kernel for usage by _SysIntVecAlloc() */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-12 10:12:36 -05:00
|
|
|
extern int _IntVecAlloc(unsigned int priority);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-12 10:12:36 -05:00
|
|
|
extern void _IntVecMarkAllocated(unsigned int vector);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-05-12 10:12:36 -05:00
|
|
|
extern void _IntVecMarkFree(unsigned int vector);
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#endif /* !_ASMLANGUAGE */
|
|
|
|
|
2015-10-04 09:32:31 -04:00
|
|
|
/* Segment selector definitions are shared */
|
2015-04-10 16:44:37 -07:00
|
|
|
#include "segselect.h"
|
|
|
|
|
|
|
|
#endif /* _ARCH_IFACE_H */
|