Xtensa port: Added kernel arch dependent structs and functions.

Change-Id: I8b35454cdaac0087b7b68b96e6ec1780c71b1e9d
Signed-off-by: Mazen NEIFER <mazen@nestwave.com>
This commit is contained in:
Mazen NEIFER 2017-01-18 22:46:13 +01:00 committed by Andrew Boie
commit b78ceec452
3 changed files with 349 additions and 0 deletions

View file

@ -0,0 +1,199 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
*
* 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
*
* 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.
*/
/**
* @file
* @brief Private kernel definitions (XTENSA)
*
* This file contains private kernel structures definitions and various
* other definitions for the XTENSA processors family architecture.
*
* This file is also included by assembly language files which must #define
* _ASMLANGUAGE before including this header file. Note that kernel
* assembly source files obtains structure offset values via "absolute symbols"
* in the offsets.o module.
*/
#ifndef _kernel_arch_data__h_
#define _kernel_arch_data__h_
#ifdef __cplusplus
extern "C" {
#endif
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <xtensa_context.h>
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
#include <kernel.h> /* public kernel API */
#include <nano_internal.h>
#include <stdint.h>
#include <misc/dlist.h>
#include <misc/util.h>
/* Bitmask definitions for the struct k_thread->flags bit field */
/* executing context is interrupt handler */
#define INT_ACTIVE (1 << 1)
/* executing context is exception handler */
#define EXC_ACTIVE (1 << 2)
/* thread uses floating point unit */
#define USE_FP 0x010
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers area not included in the definition of
* 'tPreempReg' since the interrupt stubs (_IntEnt/_IntExit)
* and exception stubs (_ExcEnt/_ExcEnter) use the stack to save and
* restore the values of these registers in order to support interrupt
* nesting. The stubs do _not_ copy the saved values from the stack
* into the TCS.
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
/*
* The following registers are considered non-volatile, i.e. callee-saved,
* but their values are pushed onto the stack rather than stored in the
* TCS structure:
*/
uint32_t retval; /* a2 */
XtExcFrame *topOfStack; /* a1 = sp */
};
typedef struct _callee_saved _callee_saved_t;
typedef struct __esf __esf_t;
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopCoprocReg {
/*
* This structure intentionally left blank. Coprocessor's registers are all
* 'volatile' and saved using the lazy context switch mechanism.
*/
} tCoopCoprocReg;
/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopCoprocReg) when a preemptive context
* switch occurs.
*/
typedef struct s_preempCoprocReg {
/*
* This structure intentionally left blank, as for now coprocessor's stack
* is positioned at top of the stack.
*/
#if XCHAL_CP_NUM > 0
char *cpStack;
#endif
} tPreempCoprocReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread. The TCS will be aligned
* to the appropriate architecture specific boundary via the
* _new_thread() call.
*/
struct _thread_arch {
/*
* See the above flag definitions above for valid bit settings. This
* field must remain near the start of struct tcs, specifically
* before any #ifdef'ed fields since the host tools currently use a
* fixed
* offset to read the 'flags' field.
*/
uint32_t flags;
int prio; /* thread priority used to sort linked list */
#ifdef CONFIG_THREAD_CUSTOM_DATA
void *custom_data; /* available for custom use */
#endif
#if defined(CONFIG_THREAD_MONITOR)
struct __thread_entry *entry; /* thread entry and parameters description */
struct tcs *next_thread; /* next item in list of ALL fiber+tasks */
#endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct tcs. This way only the
* fibers/tasks that actually utilize non-integer capabilities need to
* account for the increased memory required for storing FP state when
* sizing stacks.
*
* Given that stacks "grow down" on Xtensa, and the TCS is located
* at the start of a thread's "workspace" memory, the stacks of
* fibers/tasks that do not utilize floating point instruction can
* effectively consume the memory occupied by the 'tCoopCoprocReg' and
* 'tPreempCoprocReg' structures without ill effect.
*/
/* TODO: Move Xtensa coprocessor's stack here to get rid of extra indirection */
tCoopCoprocReg coopCoprocReg; /* non-volatile coprocessor's register storage */
tPreempCoprocReg preempCoprocReg; /* volatile coprocessor's register storage */
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
#if defined(CONFIG_DEBUG_INFO)
NANO_ISF *isf; /* ptr to interrupt stack frame */
#endif
};
typedef struct _kernel_arch _kernel_arch_t;
#endif /*! _ASMLANGUAGE && ! __ASSEMBLER__ */
/* stacks */
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
#ifdef __cplusplus
}
#endif
#endif /* _kernel_arch_data__h_ */

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
*
* 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
*
* 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 is only meant to be included by kernel_structs.h */
#ifndef _kernel_arch_func__h_
#define _kernel_arch_func__h_
#ifndef _ASMLANGUAGE
#ifdef __cplusplus
extern "C" {
#endif
/* stack alignment related macros: STACK_ALIGN_SIZE is defined above */
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
extern void FatalErrorHandler(void);
extern void ReservedInterruptHandler(unsigned int);
/* Defined in xtensa_context.S */
extern void _xt_coproc_init(void);
/**
*
* @brief Performs architecture-specific initialization
*
* This routine performs architecture-specific initialization of the nanokernel.
* Trivial stuff is done inline; more complex initialization is done via
* function calls.
*
* @return N/A
*/
static ALWAYS_INLINE void nanoArchInit(void)
{
_kernel.nested = 0;
#if XCHAL_CP_NUM > 0
/* Initialize co-processor management for tasks. Leave CPENABLE alone. */
_xt_coproc_init();
#endif
}
/**
*
* @brief Set the return value for the specified fiber (inline)
*
* @param fiber pointer to fiber
* @param value value to set as return value
*
* The register used to store the return value from a function call invocation
* is set to <value>. It is assumed that the specified <fiber> is pending, and
* thus the fibers context is stored in its TCS.
*
* @return N/A
*/
static ALWAYS_INLINE void
_set_thread_return_value(struct k_thread *thread, unsigned int value)
{
/* write into 'eax' slot created in _Swap() entry */
*(unsigned int *)(thread->callee_saved.retval) = value;
}
extern void nano_cpu_atomic_idle(unsigned int imask);
/*
* _IntLibInit() is called from the non-arch specific nanokernel function,
* _nano_init(). The IA-32 nanokernel does not require any special
* initialization of the interrupt subsystem. However, we still need to
* provide an _IntLibInit() of some sort to prevent build errors.
*/
static inline void _IntLibInit(void)
{
}
#include <stddef.h> /* For size_t */
#ifdef __cplusplus
}
#endif
#define _is_in_isr() (_kernel.nested != 0)
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_func__h_ */

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
*
* 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
*
* 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.
*/
/**
* @file
* @brief XTENSA nanokernel declarations to start a task
*
* XTENSA-specific parts of start_task().
*
* Currently empty, only here for abstraction.
*/
#ifndef _START_TASK_ARCH__H_
#define _START_TASK_ARCH__H_
#include <toolchain.h>
#include <sections.h>
#include <micro_private.h>
#include <kernel_structs.h>
#include <microkernel/task.h>
#ifdef __cplusplus
extern "C" {
#endif
#define _START_TASK_ARCH(task, opt_ptr) \
do {/* nothing */ \
} while ((0))
#ifdef __cplusplus
}
#endif
#endif /* _START_TASK_ARCH__H_ */