2015-04-10 16:44:37 -07:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013-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-12-04 10:09:39 -05:00
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief Private nanokernel definitions (ARM)
|
|
|
|
*
|
2015-10-20 09:42:33 -07:00
|
|
|
* This file contains private nanokernel structures definitions and various
|
|
|
|
* other definitions for the ARM Cortex-M3 processor architecture.
|
|
|
|
*
|
|
|
|
* This file is also included by assembly language files which must #define
|
|
|
|
* _ASMLANGUAGE before including this header file. Note that nanokernel
|
|
|
|
* assembly source files obtains structure offset values via "absolute symbols"
|
|
|
|
* in the offsets.o module.
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-06-19 11:07:02 -04:00
|
|
|
#ifndef _NANO_PRIVATE_H
|
|
|
|
#define _NANO_PRIVATE_H
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <toolchain.h>
|
|
|
|
#include <sections.h>
|
2015-05-28 10:56:47 -07:00
|
|
|
#include <arch/cpu.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
2016-09-02 16:20:19 -04:00
|
|
|
#include <kernel.h>
|
|
|
|
#include <../../../kernel/unified/include/nano_internal.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#include <stdint.h>
|
2015-06-14 14:19:10 -04:00
|
|
|
#include <misc/dlist.h>
|
2016-09-02 16:20:19 -04:00
|
|
|
#include <atomic.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
2016-03-02 17:31:26 -06:00
|
|
|
|
|
|
|
#ifdef CONFIG_THREAD_MONITOR
|
|
|
|
struct __thread_entry {
|
|
|
|
_thread_entry_t pEntry;
|
|
|
|
void *parameter1;
|
|
|
|
void *parameter2;
|
|
|
|
void *parameter3;
|
|
|
|
};
|
|
|
|
#endif /*CONFIG_THREAD_MONITOR*/
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
struct coop {
|
|
|
|
/*
|
2016-04-25 11:41:43 -04:00
|
|
|
* Unused for Cortex-M, which automatically saves the necessary
|
|
|
|
* registers in its exception stack frame.
|
2015-04-10 16:44:37 -07:00
|
|
|
*
|
|
|
|
* For Cortex-A, this may be:
|
|
|
|
*
|
|
|
|
* uint32_t a1; // r0
|
|
|
|
* uint32_t a2; // r1
|
|
|
|
* uint32_t a3; // r2
|
|
|
|
* uint32_t a4; // r3
|
|
|
|
* uint32_t ip; // r12
|
|
|
|
* uint32_t lr; // r14
|
|
|
|
* uint32_t pc; // r15
|
|
|
|
* uint32_t xpsr;
|
|
|
|
*/
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct __esf tESF;
|
|
|
|
|
|
|
|
struct preempt {
|
|
|
|
uint32_t v1; /* r4 */
|
|
|
|
uint32_t v2; /* r5 */
|
|
|
|
uint32_t v3; /* r6 */
|
|
|
|
uint32_t v4; /* r7 */
|
|
|
|
uint32_t v5; /* r8 */
|
|
|
|
uint32_t v6; /* r9 */
|
|
|
|
uint32_t v7; /* r10 */
|
|
|
|
uint32_t v8; /* r11 */
|
|
|
|
uint32_t psp; /* r13 */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct preempt tPreempt;
|
|
|
|
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
|
2015-08-20 11:04:01 -04:00
|
|
|
/* Bitmask definitions for the struct tcs.flags bit field */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2016-09-02 16:20:19 -04:00
|
|
|
#define K_STATIC 0x00000800
|
|
|
|
|
|
|
|
#define K_READY 0x00000000 /* Thread is ready to run */
|
|
|
|
#define K_TIMING 0x00001000 /* Thread is waiting on a timeout */
|
|
|
|
#define K_PENDING 0x00002000 /* Thread is waiting on an object */
|
|
|
|
#define K_PRESTART 0x00004000 /* Thread has not yet started */
|
|
|
|
#define K_DEAD 0x00008000 /* Thread has terminated */
|
|
|
|
#define K_SUSPENDED 0x00010000 /* Thread is suspended */
|
|
|
|
#define K_DUMMY 0x00020000 /* Not a real thread */
|
|
|
|
#define K_EXECUTION_MASK (K_TIMING | K_PENDING | K_PRESTART | \
|
|
|
|
K_DEAD | K_SUSPENDED | K_DUMMY)
|
|
|
|
|
2016-11-04 09:26:27 -05:00
|
|
|
#define K_FP_REGS 0x010 /* 1 = thread uses floating point registers */
|
2016-11-02 15:55:20 -05:00
|
|
|
#define K_ESSENTIAL 0x200 /* 1 = system thread that must not abort */
|
2015-04-10 16:44:37 -07:00
|
|
|
#define NO_METRICS 0x400 /* 1 = _Swap() not to update task metrics */
|
|
|
|
|
|
|
|
/* stacks */
|
|
|
|
|
|
|
|
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
|
|
|
|
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
|
|
|
|
|
2015-06-17 11:16:57 -04:00
|
|
|
#ifdef CONFIG_CPU_CORTEX_M
|
2015-08-20 16:46:11 -04:00
|
|
|
#include <cortex_m/stack.h>
|
|
|
|
#include <cortex_m/exc.h>
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
2016-04-25 11:41:43 -04:00
|
|
|
|
|
|
|
#ifdef CONFIG_FLOAT
|
|
|
|
struct preemp_float {
|
|
|
|
float s16;
|
|
|
|
float s17;
|
|
|
|
float s18;
|
|
|
|
float s19;
|
|
|
|
float s20;
|
|
|
|
float s21;
|
|
|
|
float s22;
|
|
|
|
float s23;
|
|
|
|
float s24;
|
|
|
|
float s25;
|
|
|
|
float s26;
|
|
|
|
float s27;
|
|
|
|
float s28;
|
|
|
|
float s29;
|
|
|
|
float s30;
|
|
|
|
float s31;
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2016-09-02 16:20:19 -04:00
|
|
|
/* 'struct tcs_base' must match the beginning of 'struct tcs' */
|
|
|
|
struct tcs_base {
|
|
|
|
sys_dnode_t k_q_node;
|
|
|
|
uint32_t flags;
|
|
|
|
int prio;
|
|
|
|
void *swap_data;
|
2016-09-09 14:20:55 -04:00
|
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
|
|
struct _timeout timeout;
|
|
|
|
#endif
|
2016-09-02 16:20:19 -04:00
|
|
|
};
|
|
|
|
|
2015-08-20 11:04:01 -04:00
|
|
|
struct tcs {
|
2016-09-02 16:20:19 -04:00
|
|
|
sys_dnode_t k_q_node; /* node object in any kernel queue */
|
|
|
|
uint32_t flags;
|
|
|
|
int prio;
|
|
|
|
void *swap_data;
|
2016-09-09 14:20:55 -04:00
|
|
|
#ifdef CONFIG_NANO_TIMEOUTS
|
|
|
|
struct _timeout timeout;
|
2016-09-02 16:20:19 -04:00
|
|
|
#endif
|
|
|
|
uint32_t basepri;
|
2015-08-20 11:04:01 -04:00
|
|
|
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
2015-04-10 16:44:37 -07:00
|
|
|
void *custom_data; /* available for custom use */
|
|
|
|
#endif
|
|
|
|
struct coop coopReg;
|
|
|
|
struct preempt preempReg;
|
2015-08-20 11:04:01 -04:00
|
|
|
#if defined(CONFIG_THREAD_MONITOR)
|
2016-03-02 17:31:26 -06:00
|
|
|
struct __thread_entry *entry; /* thread entry and parameters description */
|
2015-08-20 11:04:01 -04:00
|
|
|
struct tcs *next_thread; /* next item in list of ALL fiber+tasks */
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
2015-12-04 15:12:03 -05:00
|
|
|
#ifdef CONFIG_ERRNO
|
|
|
|
int errno_var;
|
|
|
|
#endif
|
2016-09-02 16:20:19 -04:00
|
|
|
atomic_t sched_locked;
|
|
|
|
void *init_data;
|
|
|
|
void (*fn_abort)(void);
|
2016-04-25 11:41:43 -04:00
|
|
|
#ifdef CONFIG_FLOAT
|
|
|
|
/*
|
|
|
|
* No cooperative floating point register set structure exists for
|
|
|
|
* the Cortex-M as it automatically saves the necessary registers
|
|
|
|
* in its exception stack frame.
|
|
|
|
*/
|
|
|
|
struct preemp_float preemp_float_regs;
|
|
|
|
#endif
|
2015-04-10 16:44:37 -07:00
|
|
|
};
|
|
|
|
|
2016-09-02 16:20:19 -04:00
|
|
|
struct ready_q {
|
unified: cache the next thread to run
When adding a thread to the ready queue, it is often known at that time
if the thread added will be the next one to run or not. So, instead of
simply updating the ready queues and the bitmask, also cache what that
thread is, so that when the scheduler is invoked, it can simply fetch it
from there. This is only done if there is a thread in the cache, since
the way the cache is updated is by comparing the priorities of the
thread being added and the cached thread.
When a thread is removed from the ready queue, if it is currently the
cached thread, it is also removed from the cache. The cache is not
updated at this time, since this would be a preemptive fetching that
could be overriden before the newly cached thread would even be
scheduled in.
Finally, when a thread is scheduled in, it now becomes the cached thread
since the fact that it is running means that by definition it was the
next one to run.
Doing this can speed up considerably some context switch times,
especially when a thread is preempted by an interrupt and the same
thread is scheduled when the interrupt exits.
Change-Id: I6dc8391cfca566699bb9b217eafe6bc6a063c8bb
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
2016-09-30 13:44:58 -04:00
|
|
|
struct k_thread *cache;
|
2016-09-02 16:20:19 -04:00
|
|
|
uint32_t prio_bmap[1];
|
|
|
|
sys_dlist_t q[K_NUM_PRIORITIES];
|
|
|
|
};
|
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
struct s_NANO {
|
2015-08-20 11:04:01 -04:00
|
|
|
struct tcs *current; /* currently scheduled thread (fiber or task) */
|
2015-04-10 16:44:37 -07:00
|
|
|
|
2015-08-20 11:04:01 -04:00
|
|
|
#if defined(CONFIG_THREAD_MONITOR)
|
|
|
|
struct tcs *threads; /* singly linked list of ALL fiber+tasks */
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_FP_SHARING
|
2015-08-20 11:04:01 -04:00
|
|
|
struct tcs *current_fp; /* thread (fiber or task) that owns the FP regs */
|
2015-04-10 16:44:37 -07:00
|
|
|
#endif /* CONFIG_FP_SHARING */
|
|
|
|
|
2016-03-18 16:43:40 -07:00
|
|
|
#ifdef CONFIG_SYS_POWER_MANAGEMENT
|
2015-04-10 16:44:37 -07:00
|
|
|
int32_t idle; /* Number of ticks for kernel idling */
|
2016-03-18 16:43:40 -07:00
|
|
|
#endif
|
2015-06-14 14:19:10 -04:00
|
|
|
|
2016-03-10 11:18:05 -05:00
|
|
|
#if defined(CONFIG_NANO_TIMEOUTS) || defined(CONFIG_NANO_TIMERS)
|
2015-06-14 14:19:10 -04:00
|
|
|
sys_dlist_t timeout_q;
|
2016-09-19 13:53:33 -04:00
|
|
|
#endif
|
2016-09-02 16:20:19 -04:00
|
|
|
struct ready_q ready_q;
|
2015-04-10 16:44:37 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct s_NANO tNANO;
|
2015-05-08 17:12:45 -05:00
|
|
|
extern tNANO _nanokernel;
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
|
|
extern void _FaultInit(void);
|
|
|
|
extern void _CpuIdleInit(void);
|
|
|
|
static ALWAYS_INLINE void nanoArchInit(void)
|
|
|
|
{
|
|
|
|
_InterruptStackSetup();
|
|
|
|
_ExcSetup();
|
|
|
|
_FaultInit();
|
|
|
|
_CpuIdleInit();
|
|
|
|
}
|
|
|
|
|
2015-07-01 17:22:39 -04:00
|
|
|
/**
|
|
|
|
*
|
2015-07-01 17:51:40 -04:00
|
|
|
* @brief Set the return value for the specified fiber (inline)
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
|
|
|
* The register used to store the return value from a function call invocation
|
|
|
|
* to <value>. It is assumed that the specified <fiber> is pending, and thus
|
2015-08-20 11:04:01 -04:00
|
|
|
* the fiber's thread is stored in its struct tcs structure.
|
2015-07-01 17:22:39 -04:00
|
|
|
*
|
2015-10-20 09:42:33 -07:00
|
|
|
* @param fiber pointer to the fiber
|
|
|
|
* @param value is the value to set as a return value
|
|
|
|
*
|
2015-07-01 17:29:04 -04:00
|
|
|
* @return N/A
|
2015-07-01 17:22:39 -04:00
|
|
|
*/
|
2015-10-20 09:42:33 -07:00
|
|
|
static ALWAYS_INLINE void fiberRtnValueSet(struct tcs *fiber,
|
|
|
|
unsigned int value)
|
2015-04-10 16:44:37 -07:00
|
|
|
{
|
|
|
|
tESF *pEsf = (void *)fiber->preempReg.psp;
|
2015-04-14 17:15:52 -05:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
pEsf->a1 = value;
|
|
|
|
}
|
|
|
|
|
2016-11-03 13:00:41 -07:00
|
|
|
#define _current _nanokernel.current
|
|
|
|
#define _ready_q _nanokernel.ready_q
|
|
|
|
#define _timeout_q _nanokernel.timeout_q
|
|
|
|
#define _set_thread_return_value fiberRtnValueSet
|
|
|
|
|
2016-09-02 16:20:19 -04:00
|
|
|
static ALWAYS_INLINE void
|
|
|
|
_set_thread_return_value_with_data(struct k_thread *thread, unsigned int value,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
_set_thread_return_value(thread, value);
|
|
|
|
thread->swap_data = data;
|
|
|
|
}
|
2016-11-03 13:00:41 -07:00
|
|
|
|
|
|
|
#define _IDLE_THREAD_PRIO (CONFIG_NUM_PREEMPT_PRIORITIES)
|
2016-09-02 16:20:19 -04:00
|
|
|
|
2015-04-10 16:44:37 -07:00
|
|
|
extern void nano_cpu_atomic_idle(unsigned int);
|
|
|
|
|
2016-09-02 16:20:19 -04:00
|
|
|
#define _is_in_isr() _IsInIsr()
|
2015-04-10 16:44:37 -07:00
|
|
|
|
|
|
|
extern void _IntLibInit(void);
|
|
|
|
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-06-19 11:07:02 -04:00
|
|
|
#endif /* _NANO_PRIVATE_H */
|