1. Add hw_tags.c, which will call arm64_mte to implement tagging of memory blocks by operating registers 2. It has been able to run normally on the default NX memory allocator, excluding mempool and tlsf 3. On more complex configurations, memory tests such as memstress can run normally without system crashes Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
3134 lines
113 KiB
C
3134 lines
113 KiB
C
/****************************************************************************
|
|
* include/nuttx/arch.h
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* 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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __INCLUDE_NUTTX_ARCH_H
|
|
#define __INCLUDE_NUTTX_ARCH_H
|
|
|
|
/* This header file contains function prototypes for the interfaces between
|
|
* (1) the nuttx core-code, (2) the microprocessor specific logic that
|
|
* resides under the arch/ sub-directory, and (3) the board-specific logic
|
|
* that resides under boards/
|
|
*
|
|
* Naming conventions:
|
|
*
|
|
* 1. Common Microprocessor Interfaces.
|
|
*
|
|
* Any interface that is common across all microprocessors should be
|
|
* prefixed with up_ and prototyped in this header file. These
|
|
* definitions provide the common interface between NuttX and the
|
|
* architecture-specific implementation in arch/
|
|
*
|
|
* This chip related declarations are retained in this header file.
|
|
*
|
|
* NOTE: up_ is supposed to stand for microprocessor; the u is like the
|
|
* Greek letter micron.
|
|
*
|
|
* 2. Microprocessor-Specific Interfaces.
|
|
*
|
|
* An interface which is unique to a certain microprocessor should be
|
|
* prefixed with the name of the microprocessor, for example stm32_,
|
|
* and be prototyped in some header file in the arch/ directories.
|
|
*
|
|
* There is also a arch/<architecture>/include/<chip>/chip.h header file
|
|
* that can be used to communicate other microprocessor-specific
|
|
* information between the board logic and even application logic.
|
|
* Application logic may, for example, need to know specific capabilities
|
|
* of the chip. Prototypes in that chip.h header file should follow the
|
|
* microprocessor specific naming convention.
|
|
*
|
|
* 3. Common Board Interfaces.
|
|
*
|
|
* Any interface that is common across all boards should be prefixed
|
|
* with board_ and should be prototyped in the board.h header file.
|
|
* These board_ definitions provide the interface between the board-level
|
|
* logic and the architecture-specific logic.
|
|
*
|
|
* 4. Board-Specific Interfaces.
|
|
*
|
|
* Any interface that is unique to a board should be prefixed with
|
|
* the board name, for example stm32f4discovery_. Sometimes the board
|
|
* name is too long so stm32_ would be okay too. These should be
|
|
* prototyped in boards/<arch>/<chip><board>/src/<board>.h and should
|
|
* not be used outside of that board directory since board-specific
|
|
* definitions have no meaning outside of the board directory.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#include <arch/arch.h>
|
|
#include <arch/types.h>
|
|
|
|
#include <nuttx/compiler.h>
|
|
#include <nuttx/cache.h>
|
|
#include <nuttx/sched.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor definitions
|
|
****************************************************************************/
|
|
|
|
#define DEBUGPOINT_NONE 0x00
|
|
#define DEBUGPOINT_WATCHPOINT_RO 0x01
|
|
#define DEBUGPOINT_WATCHPOINT_WO 0x02
|
|
#define DEBUGPOINT_WATCHPOINT_RW 0x03
|
|
#define DEBUGPOINT_BREAKPOINT 0x04
|
|
#define DEBUGPOINT_STEPPOINT 0x05
|
|
|
|
/****************************************************************************
|
|
* Name: up_cpu_index
|
|
*
|
|
* Description:
|
|
* Return the real core number regardless CONFIG_SMP setting
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_ARCH_HAVE_MULTICPU
|
|
# define up_cpu_index() 0
|
|
#endif /* CONFIG_ARCH_HAVE_MULTICPU */
|
|
|
|
/****************************************************************************
|
|
* Name: up_this_cpu
|
|
*
|
|
* Description:
|
|
* Return the logical core number. Default implementation is 1:1 mapping,
|
|
* i.e. physical=logical.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_ARCH_HAVE_CPUID_MAPPING
|
|
# define up_this_cpu() up_cpu_index()
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
typedef CODE void (*phy_enable_t)(bool enable);
|
|
typedef CODE void (*initializer_t)(void);
|
|
typedef CODE void (*debug_callback_t)(int type, FAR void *addr, size_t size,
|
|
FAR void *arg);
|
|
|
|
/****************************************************************************
|
|
* Public Data
|
|
****************************************************************************/
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
#define EXTERN extern "C"
|
|
extern "C"
|
|
{
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP
|
|
/* By default, the RTOS tickless logic assumes that the range of times that
|
|
* can be represented by the underlying hardware timer is so large that no
|
|
* special precautions need to be taken. That is not always the case. If
|
|
* there is a limit to the maximum timing interval that can be represented by
|
|
* the timer, then that limit must be respected.
|
|
*
|
|
* If CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP is defined, then use a 32-bit
|
|
* global variable called g_oneshot_maxticks variable is enabled. This
|
|
* variable is initialized by platform-specific logic at runtime to the
|
|
* maximum delay that the timer can wait (in configured clock ticks).
|
|
* The RTOS tickless logic will then limit all requested delays to this
|
|
* value (in ticks).
|
|
*/
|
|
|
|
EXTERN uint32_t g_oneshot_maxticks;
|
|
#endif
|
|
|
|
#ifdef CONFIG_RTC
|
|
/* Variable determines the state of the RTC module.
|
|
*
|
|
* After initialization value is set to 'true' if RTC starts successfully.
|
|
* The value can be changed to false also during operation if RTC for
|
|
* some reason fails.
|
|
*/
|
|
|
|
EXTERN volatile bool g_rtc_enabled;
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE
|
|
/* This is the interrupt vector mapping table. This must be provided by
|
|
* architecture specific logic if CONFIG_ARCH_MINIMAL_VECTORTABLE is define
|
|
* in the configuration. See declaration in include/nuttx/irq.h
|
|
*/
|
|
|
|
/* EXTERN const irq_mapped_t g_irqmap[NR_IRQS]; */
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAVE_CXXINITIALIZE
|
|
/* _sinit and _einit are symbols exported by the linker script that mark the
|
|
* beginning and the end of the C++ initialization section.
|
|
*/
|
|
|
|
extern initializer_t _sinit[];
|
|
extern initializer_t _einit[];
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Public Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* These are standard interfaces that must be exported to the base RTOS
|
|
* logic from architecture-specific code.
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_fork
|
|
*
|
|
* Description:
|
|
* The up_fork() function is the base of fork() function that provided in
|
|
* libc, and fork() is implemented as a wrapper of up_fork() function.
|
|
*
|
|
* Returned Value:
|
|
* Upon successful completion, up_fork() returns 0 to the child process
|
|
* and returns the process ID of the child process to the parent process.
|
|
* Otherwise, -1 is returned to the parent, no child process is created,
|
|
* and errno is set to indicate the error.
|
|
*
|
|
****************************************************************************/
|
|
|
|
pid_t up_fork(void);
|
|
|
|
/****************************************************************************
|
|
* Name: up_initialize
|
|
*
|
|
* Description:
|
|
* up_initialize will be called once during OS initialization after the
|
|
* basic OS services have been initialized. The architecture specific
|
|
* details of initializing the OS will be handled here. Such things as
|
|
* setting up interrupt service routines, starting the clock, and
|
|
* registering device drivers are some of the things that are different
|
|
* for each processor and hardware platform.
|
|
*
|
|
* up_initialize is called after the OS initialized but before the initial
|
|
* application has been started and before the libraries have been
|
|
* initialized. OS services and driver services are available.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_initialize(void);
|
|
|
|
/****************************************************************************
|
|
* Name: up_systempoweroff
|
|
*
|
|
* Description:
|
|
* The function up_systempoweroff() will power down the MCU. Optional!
|
|
* Availability of this function is dependent upon the architecture
|
|
* support.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_systempoweroff(void) noreturn_function;
|
|
|
|
/****************************************************************************
|
|
* Name: up_systemreset
|
|
*
|
|
* Description:
|
|
* The function up_systemreset() will reset the MCU. Optional!
|
|
* Availability of this function is dependent upon the architecture
|
|
* support.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_systemreset(void) noreturn_function;
|
|
|
|
/****************************************************************************
|
|
* Name: up_idle
|
|
*
|
|
* Description:
|
|
* up_idle() is the logic that will be executed when there is no other
|
|
* ready-to-run task. This is processor idle time and will continue until
|
|
* some interrupt occurs to cause a context switch from the idle task.
|
|
*
|
|
* Processing in this state may be processor-specific. e.g.,
|
|
* this is where power management operations might be performed.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_idle(void);
|
|
|
|
/****************************************************************************
|
|
* Name: up_initial_state
|
|
*
|
|
* Description:
|
|
* A new thread is being started and a new TCB has been created.
|
|
* This function is called to initialize the processor specific portions
|
|
* of the new TCB.
|
|
*
|
|
* This function must setup the initial architecture registers and/or
|
|
* stack so that execution will begin at tcb->start on the next context
|
|
* switch.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_initial_state(FAR struct tcb_s *tcb);
|
|
|
|
/****************************************************************************
|
|
* Name: up_create_stack
|
|
*
|
|
* Description:
|
|
* Allocate a stack for a new thread and setup up stack-related information
|
|
* in the TCB.
|
|
*
|
|
* The following TCB fields must be initialized by this function:
|
|
*
|
|
* - adj_stack_size: Stack size after adjustment for hardware, processor,
|
|
* etc. This value is retained only for debug purposes.
|
|
* - stack_alloc_ptr: Pointer to allocated stack
|
|
* - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
|
|
* Arguments has been removed from the stack allocation.
|
|
*
|
|
* Input Parameters:
|
|
* - tcb: The TCB of new task
|
|
* - stack_size: The requested stack size. At least this much
|
|
* must be allocated.
|
|
* - ttype: The thread type. This may be one of following (defined in
|
|
* include/nuttx/sched.h):
|
|
*
|
|
* TCB_FLAG_TTYPE_TASK Normal user task
|
|
* TCB_FLAG_TTYPE_PTHREAD User pthread
|
|
* TCB_FLAG_TTYPE_KERNEL Kernel thread
|
|
*
|
|
* This thread type is normally available in the flags field of the TCB,
|
|
* however, there are certain contexts where the TCB may not be fully
|
|
* initialized when up_create_stack is called.
|
|
*
|
|
* If CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are is defined, then
|
|
* this thread type may affect how the stack is allocated. For example,
|
|
* kernel thread stacks should be allocated from protected kernel memory.
|
|
* Stacks for user tasks and threads must come from memory that is
|
|
* accessible to user code.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype);
|
|
|
|
/****************************************************************************
|
|
* Name: up_use_stack
|
|
*
|
|
* Description:
|
|
* Setup stack-related information in the TCB using pre-allocated stack
|
|
* memory. This function is called only from nxtask_init() when a task or
|
|
* kernel thread is started (never for pthreads).
|
|
*
|
|
* The following TCB fields must be initialized:
|
|
*
|
|
* - adj_stack_size: Stack size after adjustment for hardware,
|
|
* processor, etc. This value is retained only for debug
|
|
* purposes.
|
|
* - stack_alloc_ptr: Pointer to allocated stack
|
|
* - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
|
|
* Arguments has been removed from the stack allocation.
|
|
*
|
|
* Input Parameters:
|
|
* - tcb: The TCB of new task
|
|
* - stack: The new stack to be used.
|
|
* - stack_size: The allocated stack size.
|
|
*
|
|
* NOTE: Unlike up_stack_create() and up_stack_release, this function
|
|
* does not require the task type (ttype) parameter. The TCB flags will
|
|
* always be set to provide the task type to up_use_stack() if it needs
|
|
* that information.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size);
|
|
|
|
/****************************************************************************
|
|
* Name: up_stack_frame
|
|
*
|
|
* Description:
|
|
* Allocate a stack frame in the TCB's stack to hold thread-specific data.
|
|
* This function may be called any time after up_create_stack() or
|
|
* up_use_stack() have been called but before the task has been started.
|
|
*
|
|
* Thread data may be kept in the stack (instead of in the TCB) if it is
|
|
* accessed by the user code directly. This includes such things as
|
|
* argv[]. The stack memory is guaranteed to be in the same protection
|
|
* domain as the thread.
|
|
*
|
|
* The following TCB fields will be re-initialized:
|
|
*
|
|
* - adj_stack_size: Stack size after removal of the stack frame from
|
|
* the stack
|
|
* - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
|
|
* Arguments has been removed from the stack allocation.
|
|
*
|
|
* Here is the diagram after some allocation(tls, arg):
|
|
*
|
|
* +-------------+ <-stack_alloc_ptr(lowest)
|
|
* | TLS Data |
|
|
* +-------------+
|
|
* | Arguments |
|
|
* stack_base_ptr-> +-------------+\
|
|
* | Available | +
|
|
* | Stack | |
|
|
* | | | |
|
|
* | | | +->adj_stack_size
|
|
* v | | |
|
|
* | | |
|
|
* | | +
|
|
* +-------------+/
|
|
*
|
|
* Input Parameters:
|
|
* - tcb: The TCB of new task
|
|
* - frame_size: The size of the stack frame to allocate.
|
|
*
|
|
* Returned Value:
|
|
* - A pointer to bottom of the allocated stack frame. NULL will be
|
|
* returned on any failures. The alignment of the returned value is
|
|
* the same as the alignment of the stack itself.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size);
|
|
|
|
/****************************************************************************
|
|
* Name: up_release_stack
|
|
*
|
|
* Description:
|
|
* A task has been stopped. Free all stack related resources retained in
|
|
* the defunct TCB.
|
|
*
|
|
* Input Parameters:
|
|
* - dtcb: The TCB containing information about the stack to be released
|
|
* - ttype: The thread type. This may be one of following (defined in
|
|
* include/nuttx/sched.h):
|
|
*
|
|
* TCB_FLAG_TTYPE_TASK Normal user task
|
|
* TCB_FLAG_TTYPE_PTHREAD User pthread
|
|
* TCB_FLAG_TTYPE_KERNEL Kernel thread
|
|
*
|
|
* This thread type is normally available in the flags field of the TCB,
|
|
* however, there are certain error recovery contexts where the TCB may
|
|
* not be fully initialized when up_release_stack is called.
|
|
*
|
|
* If CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL are defined, then
|
|
* this thread type may affect how the stack is freed. For example,
|
|
* kernel thread stacks may have been allocated from protected kernel
|
|
* memory. Stacks for user tasks and threads must have come from memory
|
|
* that is accessible to user code.
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype);
|
|
|
|
/****************************************************************************
|
|
* Name: up_switch_context
|
|
*
|
|
* Description:
|
|
* A task is currently in the ready-to-run list but has been prepped
|
|
* to execute. Restore its context, and start execution.
|
|
*
|
|
* This function is called only from the NuttX scheduling
|
|
* logic. Interrupts will always be disabled when this
|
|
* function is called.
|
|
*
|
|
* Input Parameters:
|
|
* tcb: Refers to the head task of the ready-to-run list
|
|
* which will be executed.
|
|
* rtcb: Refers to the running task which will be blocked.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef up_switch_context
|
|
void up_switch_context(FAR struct tcb_s *tcb, FAR struct tcb_s *rtcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_exit
|
|
*
|
|
* Description:
|
|
* This function causes the currently executing task to cease
|
|
* to exist. This is a special case of task_delete() where the task to
|
|
* be deleted is the currently executing task. It is more complex because
|
|
* a context switch must be perform to the next ready to run task.
|
|
*
|
|
* Unlike other UP APIs, this function may be called directly from user
|
|
* programs in various states. The implementation of this function should
|
|
* disable interrupts before performing scheduling operations.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_exit(int status) noreturn_function;
|
|
|
|
/* Prototype is in unistd.h */
|
|
|
|
/****************************************************************************
|
|
* Name: up_dump_register
|
|
*
|
|
* Description:
|
|
* Register dump may be handled in an architecture-specific way.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_dump_register(FAR void *regs);
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_BACKTRACE
|
|
|
|
/****************************************************************************
|
|
* Name: up_backtrace
|
|
*
|
|
* Description:
|
|
* up_backtrace() returns a backtrace for the TCB, in the array
|
|
* pointed to by buffer. A backtrace is the series of currently active
|
|
* function calls for the program. Each item in the array pointed to by
|
|
* buffer is of type void *, and is the return address from the
|
|
* corresponding stack frame. The size argument specifies the maximum
|
|
* number of addresses that can be stored in buffer. If the backtrace is
|
|
* larger than size, then the addresses corresponding to the size most
|
|
* recent function calls are returned; to obtain the complete backtrace,
|
|
* make sure that buffer and size are large enough.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - Address of the task's TCB, NULL means dump the running task
|
|
* buffer - Return address from the corresponding stack frame
|
|
* size - Maximum number of addresses that can be stored in buffer
|
|
* skip - number of addresses to be skipped
|
|
*
|
|
* Returned Value:
|
|
* up_backtrace() returns the number of addresses returned in buffer
|
|
*
|
|
* Assumptions:
|
|
* Have to make sure tcb keep safe during function executing, it means
|
|
* 1. Tcb have to be self or not-running. In SMP case, the running task
|
|
* PC & SP cannot be backtrace, as whose get from tcb is not the newest.
|
|
* 2. Tcb have to keep not be freed. In task exiting case, have to
|
|
* make sure the tcb get from pid and up_backtrace in one critical
|
|
* section procedure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_backtrace(FAR struct tcb_s *tcb,
|
|
FAR void **buffer, int size, int skip);
|
|
#endif /* CONFIG_ARCH_HAVE_BACKTRACE */
|
|
|
|
/****************************************************************************
|
|
* Name: up_schedule_sigaction
|
|
*
|
|
* Description:
|
|
* This function is called by the OS when one or more
|
|
* signal handling actions have been queued for execution.
|
|
* The architecture specific code must configure things so
|
|
* that the 'sigdeliver' callback is executed on the thread
|
|
* specified by 'tcb' as soon as possible.
|
|
*
|
|
* This function may be called from interrupt handling logic.
|
|
*
|
|
* This operation should not cause the task to be unblocked
|
|
* nor should it cause any immediate execution of sigdeliver.
|
|
* Typically, a few cases need to be considered:
|
|
*
|
|
* (1) This function may be called from an interrupt handler
|
|
* During interrupt processing, all xcptcontext structures
|
|
* should be valid for all tasks. That structure should
|
|
* be modified to invoke sigdeliver() either on return
|
|
* from (this) interrupt or on some subsequent context
|
|
* switch to the recipient task.
|
|
* (2) If not in an interrupt handler and the tcb is NOT
|
|
* the currently executing task, then again just modify
|
|
* the saved xcptcontext structure for the recipient
|
|
* task so it will invoke sigdeliver when that task is
|
|
* later resumed.
|
|
* (3) If not in an interrupt handler and the tcb IS the
|
|
* currently executing task -- just call the signal
|
|
* handler now.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_schedule_sigaction(FAR struct tcb_s *tcb);
|
|
|
|
/****************************************************************************
|
|
* Name: up_task_start
|
|
*
|
|
* Description:
|
|
* In this kernel mode build, this function will be called to execute a
|
|
* task in user-space. When the task is first started, a kernel-mode
|
|
* stub will first run to perform some housekeeping functions. This
|
|
* kernel-mode stub will then be called transfer control to the user-mode
|
|
* task by calling this function.
|
|
*
|
|
* Normally the a user-mode start-up stub will also execute before the
|
|
* task actually starts. See libc/sched/task_startup.c
|
|
*
|
|
* Input Parameters:
|
|
* taskentry - The user-space entry point of the task.
|
|
* argc - The number of parameters being passed.
|
|
* argv - The parameters being passed. These lie in kernel-space memory
|
|
* and will have to be reallocated in user-space memory.
|
|
*
|
|
* Returned Value:
|
|
* This function should not return. It should call the user-mode start-up
|
|
* stub and that stub should call exit if/when the user task terminates.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
void up_task_start(main_t taskentry, int argc, FAR char *argv[])
|
|
noreturn_function;
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_pthread_start
|
|
*
|
|
* Description:
|
|
* In this kernel mode build, this function will be called to execute a
|
|
* pthread in user-space. When the pthread is first started, a kernel-mode
|
|
* stub will first run to perform some housekeeping functions. This
|
|
* kernel-mode stub will then be called transfer control to the user-mode
|
|
* pthread by calling this function.
|
|
*
|
|
* Normally the a user-mode start-up stub will also execute before the
|
|
* pthread actually starts. See libc/pthread/pthread_create.c
|
|
*
|
|
* Input Parameters:
|
|
* startup - The user-space pthread startup function
|
|
* entrypt - The user-space address of the pthread entry point
|
|
* arg - Standard argument for the pthread entry point
|
|
*
|
|
* Returned Value:
|
|
* This function should not return. It should call the user-mode start-up
|
|
* stub and that stub should call pthread_exit if/when the user pthread
|
|
* terminates.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
|
|
!defined(CONFIG_DISABLE_PTHREAD)
|
|
void up_pthread_start(pthread_trampoline_t startup,
|
|
pthread_startroutine_t entrypt, pthread_addr_t arg)
|
|
noreturn_function;
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_signal_dispatch
|
|
*
|
|
* Description:
|
|
* In this kernel mode build, this function will be called to execute a
|
|
* a signal handler in user-space. When the signal is delivered, a
|
|
* kernel-mode stub will first run to perform some housekeeping functions.
|
|
* This kernel-mode stub will then be called transfer control to the user
|
|
* mode signal handler by calling this function.
|
|
*
|
|
* Normally the a architecture, user-mode signal handling stub will also
|
|
* execute before the ultimate signal handler is called. That stub
|
|
* function is the user-space, signal handler trampoline function. It is
|
|
* called from up_signal_dispatch() in user-mode.
|
|
*
|
|
* Input Parameters:
|
|
* sighand - The address user-space signal handling function
|
|
* signo, info, and ucontext - Standard arguments to be passed to the
|
|
* signal handling function.
|
|
*
|
|
* Returned Value:
|
|
* None. This function does not return in the normal sense. It returns
|
|
* via an architecture specific system call made by up_signal_handler()
|
|
* (see below). However, this will look like a normal return by the
|
|
* caller of up_signal_dispatch.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
|
|
void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
|
|
FAR siginfo_t *info, FAR void *ucontext);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_signal_handler
|
|
*
|
|
* Description:
|
|
* This function is the user-space, signal handler trampoline function that
|
|
* must be provided by architecture-specific logic. It is called from
|
|
* up_signal_dispatch() in user-mode.
|
|
*
|
|
* Input Parameters:
|
|
* sighand - The address user-space signal handling function
|
|
* signo, info, and ucontext - Standard arguments to be passed to the
|
|
* signal handling function.
|
|
*
|
|
* Returned Value:
|
|
* None. This function does not return in the normal sense. It returns
|
|
* via an architecture specific system call.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
|
|
void up_signal_handler(_sa_sigaction_t sighand, int signo,
|
|
FAR siginfo_t *info, FAR void *ucontext)
|
|
noreturn_function;
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_allocate_heap
|
|
*
|
|
* Description:
|
|
* This function will be called to dynamically set aside the heap region.
|
|
*
|
|
* For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
|
|
* user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
|
|
* size of the unprotected, user-space heap.
|
|
*
|
|
* If a protected kernel-space heap is provided, the kernel heap must be
|
|
* allocated (and protected) by an analogous up_allocate_kheap().
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_allocate_heap(FAR void **heap_start, size_t *heap_size);
|
|
|
|
/****************************************************************************
|
|
* Name: up_allocate_kheap
|
|
*
|
|
* Description:
|
|
* For the kernel builds (CONFIG_BUILD_PROTECTED=y or
|
|
* CONFIG_BUILD_KERNEL=y) there may be both kernel- and user-space heaps
|
|
* as determined by CONFIG_MM_KERNEL_HEAP=y. This function allocates (and
|
|
* protects) the kernel-space heap.
|
|
*
|
|
* For Flat build (CONFIG_BUILD_FLAT=y), this function enables a separate
|
|
* (although unprotected) heap for the kernel.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_MM_KERNEL_HEAP
|
|
void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_allocate_pgheap
|
|
*
|
|
* Description:
|
|
* If there is a page allocator in the configuration, then this function
|
|
* must be provided by the platform-specific code. The OS initialization
|
|
* logic will call this function early in the initialization sequence to
|
|
* get the page heap information needed to configure the page allocator.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_MM_PGALLOC
|
|
void up_allocate_pgheap(FAR void **heap_start, size_t *heap_size);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: pgalloc
|
|
*
|
|
* Description:
|
|
* If there is a page allocator in the configuration and if an MMU is
|
|
* available to map physical addresses to virtual address, then this
|
|
* function must be provided by the platform-specific code. This is part
|
|
* of the implementation of sbrk(). This function will allocate the
|
|
* requested number of pages using the page allocator and map them into
|
|
* consecutive virtual addresses beginning with 'brkaddr'
|
|
*
|
|
* NOTE: This function does not use the up_ naming standard because it
|
|
* is indirectly callable from user-space code via a system trap.
|
|
* Therefore, it is a system interface and follows a different naming
|
|
* convention.
|
|
*
|
|
* Input Parameters:
|
|
* brkaddr - The heap break address. The next page will be allocated and
|
|
* mapped to this address. Must be page aligned. If the memory manager
|
|
* has not yet been initialized and this is the first block requested for
|
|
* the heap, then brkaddr should be zero. pgalloc will then assigned the
|
|
* well-known virtual address of the beginning of the heap.
|
|
* npages - The number of pages to allocate and map. Mapping of pages
|
|
* will be contiguous beginning beginning at 'brkaddr'
|
|
*
|
|
* Returned Value:
|
|
* The (virtual) base address of the mapped page will be returned on
|
|
* success.
|
|
* Normally this will be the same as the 'brkaddr' input. However, if
|
|
* the 'brkaddr' input was zero, this will be the virtual address of the
|
|
* beginning of the heap. Zero is returned on any failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \
|
|
defined(CONFIG_ARCH_USE_MMU)
|
|
uintptr_t pgalloc(uintptr_t brkaddr, unsigned int npages);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_extraheaps_init
|
|
*
|
|
* Description:
|
|
* Initialize any extra heap.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_HAVE_EXTRA_HEAPS)
|
|
void up_extraheaps_init(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_textheap_memalign
|
|
*
|
|
* Description:
|
|
* Allocate memory for text with the specified alignment and sectname.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
|
# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION)
|
|
FAR void *up_textheap_memalign(FAR const char *sectname,
|
|
size_t align, size_t size);
|
|
# else
|
|
FAR void *up_textheap_memalign(size_t align, size_t size);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_textheap_free
|
|
*
|
|
* Description:
|
|
* Free memory allocated for text sections.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
|
void up_textheap_free(FAR void *p);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_textheap_heapmember
|
|
*
|
|
* Description:
|
|
* Test if memory is from text heap.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
|
bool up_textheap_heapmember(FAR void *p);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_textheap_data_address
|
|
*
|
|
* Description:
|
|
* If an instruction bus address is specified, return the corresponding
|
|
* data bus address. Otherwise, return the given address as it is.
|
|
*
|
|
* For some platforms, up_textheap_memalign() might return memory regions
|
|
* with separate instruction/data bus mappings. In that case,
|
|
* up_textheap_memalign() returns the address of the instruction bus
|
|
* mapping.
|
|
* The instruction bus mapping might provide only limited data access.
|
|
* (For example, only read-only, word-aligned access.)
|
|
* You can use up_textheap_data_address() to query the corresponding data
|
|
* bus mapping.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
|
#if defined(CONFIG_ARCH_HAVE_TEXT_HEAP_SEPARATE_DATA_ADDRESS)
|
|
FAR void *up_textheap_data_address(FAR void *p);
|
|
#else
|
|
#define up_textheap_data_address(p) ((FAR void *)p)
|
|
#endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_textheap_data_sync
|
|
*
|
|
* Description:
|
|
* Ensure modifications made on the data bus addresses (the addresses
|
|
* returned by up_textheap_data_address) fully visible on the corresponding
|
|
* instruction bus addresses.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
|
#if defined(CONFIG_ARCH_HAVE_TEXT_HEAP_SEPARATE_DATA_ADDRESS)
|
|
void up_textheap_data_sync(void);
|
|
#else
|
|
#define up_textheap_data_sync() do {} while (0)
|
|
#endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_dataheap_memalign
|
|
*
|
|
* Description:
|
|
* Allocate memory for data with the specified alignment and sectname.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
|
# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION)
|
|
FAR void *up_dataheap_memalign(FAR const char *sectname,
|
|
size_t align, size_t size);
|
|
# else
|
|
FAR void *up_dataheap_memalign(size_t align, size_t size);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_dataheap_free
|
|
*
|
|
* Description:
|
|
* Free memory allocated for data sections.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
|
void up_dataheap_free(FAR void *p);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_dataheap_heapmember
|
|
*
|
|
* Description:
|
|
* Test if memory is from data heap.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
|
bool up_dataheap_heapmember(FAR void *p);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_copy_section
|
|
*
|
|
* Description:
|
|
* This function copies a section from a general temporary buffer (src) to
|
|
* a specific address (dest). This is typically used in architectures that
|
|
* require specific handling of memory sections.
|
|
*
|
|
* Input Parameters:
|
|
* dest - A pointer to the destination where the data needs to be copied.
|
|
* src - A pointer to the source from where the data needs to be copied.
|
|
* n - The number of bytes to be copied from src to dest.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
#if defined(CONFIG_ARCH_USE_COPY_SECTION)
|
|
int up_copy_section(FAR void *dest, FAR const void *src, size_t n);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_setpicbase and up_getpicbase
|
|
*
|
|
* Description:
|
|
* It NXFLAT external modules (or any other binary format that requires
|
|
* PIC) are supported, then these macros must defined to (1) set or get
|
|
* the PIC base register value. These must be implemented with in-line
|
|
* assembly.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_PIC
|
|
# define up_setpicbase(picbase)
|
|
# define up_getpicbase(ppicbase)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Percpu support
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_update_task
|
|
*
|
|
* Description:
|
|
* We can utilize percpu storage to hold information about the
|
|
* current running task. If we intend to implement this feature, we would
|
|
* need to define two macros that help us manage this percpu information
|
|
* effectively.
|
|
*
|
|
* up_this_task: This macro is designed to read the contents of the percpu
|
|
* register to retrieve information about the current
|
|
* running task.This allows us to quickly access
|
|
* task-specific data without having to disable interrupts,
|
|
* access global variables and obtain the current cpu index.
|
|
*
|
|
* up_update_task: This macro is responsible for updating the contents of
|
|
* the percpu register.It is typically called during
|
|
* initialization or when a context switch occurs to ensure
|
|
* that the percpu register reflects the information of the
|
|
* newly running task.
|
|
*
|
|
* Input Parameters:
|
|
* current tcb
|
|
*
|
|
* Returned Value:
|
|
* current tcb
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef up_update_task
|
|
# define up_update_task(t)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Address Environment Interfaces
|
|
*
|
|
* Low-level interfaces used in binfmt/ to instantiate tasks with address
|
|
* environments. These interfaces all operate on type arch_addrenv_t which
|
|
* is an abstract representation of a task group's address environment and
|
|
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
|
|
*
|
|
* up_addrenv_create - Create an address environment
|
|
* up_addrenv_destroy - Destroy an address environment.
|
|
* up_addrenv_vtext - Returns the virtual base address of the .text
|
|
* address environment
|
|
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
|
|
* address environment
|
|
* up_addrenv_vheap - Returns the virtual base address of the heap
|
|
* address environment
|
|
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
|
|
* up_addrenv_select - Instantiate an address environment
|
|
* up_addrenv_clone - Copy an address environment from one location to
|
|
* another.
|
|
*
|
|
* Higher-level interfaces used by the tasking logic. These interfaces are
|
|
* used by the functions in sched/ and all operate on the thread which whose
|
|
* group been assigned an address environment by up_addrenv_clone().
|
|
*
|
|
* up_addrenv_attach - Clone the address environment assigned to one TCB
|
|
* to another. This operation is done when a pthread
|
|
* is created that share's the same address
|
|
* environment.
|
|
* up_addrenv_detach - Release the threads reference to an address
|
|
* environment when a task/thread exits.
|
|
*
|
|
* CONFIG_ARCH_STACK_DYNAMIC=y indicates that the user process stack resides
|
|
* in its own address space. This options is also *required* if
|
|
* CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why?
|
|
* Because the caller's stack must be preserved in its own address space
|
|
* when we instantiate the environment of the new process in order to
|
|
* initialize it.
|
|
*
|
|
* NOTE: The naming of the CONFIG_ARCH_STACK_DYNAMIC selection implies that
|
|
* dynamic stack allocation is supported. Certainly this option must be set
|
|
* if dynamic stack allocation is supported by a platform. But the more
|
|
* general meaning of this configuration environment is simply that the
|
|
* stack has its own address space.
|
|
*
|
|
* If CONFIG_ARCH_STACK_DYNAMIC=y is selected then the platform specific
|
|
* code must export these additional interfaces:
|
|
*
|
|
* up_addrenv_ustackalloc - Create a stack address environment
|
|
* up_addrenv_ustackfree - Destroy a stack address environment.
|
|
* up_addrenv_vustack - Returns the virtual base address of the stack
|
|
* up_addrenv_ustackselect - Instantiate a stack address environment
|
|
*
|
|
* If CONFIG_ARCH_KERNEL_STACK is selected, then each user process will have
|
|
* two stacks: (1) a large (and possibly dynamic) user stack and (2) a
|
|
* smaller kernel stack. However, this option is *required* if both
|
|
* CONFIG_BUILD_KERNEL and CONFIG_LIBC_EXECFUNCS are selected. Why? Because
|
|
* when we instantiate and initialize the address environment of the new
|
|
* user process, we will temporarily lose the address environment of the old
|
|
* user process, including its stack contents. The kernel C logic will crash
|
|
* immediately with no valid stack in place.
|
|
*
|
|
* If CONFIG_ARCH_KERNEL_STACK=y is selected then the platform specific
|
|
* code must export these additional interfaces:
|
|
*
|
|
* up_addrenv_kstackalloc - Create a stack in the kernel address
|
|
* environment
|
|
* up_addrenv_kstackfree - Destroy the kernel stack.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_create
|
|
*
|
|
* Description:
|
|
* This function is called when a new task is created in order to
|
|
* instantiate an address environment for the new task group.
|
|
* up_addrenv_create() is essentially the allocator of the physical
|
|
* memory for the new task.
|
|
*
|
|
* Input Parameters:
|
|
* textsize - The size (in bytes) of the .text address environment needed
|
|
* by the task. This region may be read/execute only.
|
|
* datasize - The size (in bytes) of the .data/.bss address environment
|
|
* needed by the task. This region may be read/write only. NOTE: The
|
|
* actual size of the data region that is allocated will include a
|
|
* OS private reserved region at the beginning. The size of the
|
|
* private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
|
|
* heapsize - The initial size (in bytes) of the heap address environment
|
|
* needed by the task. This region may be read/write only.
|
|
* addrenv - The location to return the representation of the task address
|
|
* environment.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
|
|
FAR arch_addrenv_t *addrenv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_destroy
|
|
*
|
|
* Description:
|
|
* This function is called when a final thread leaves the task group and
|
|
* the task group is destroyed. This function then destroys the defunct
|
|
* address environment, releasing the underlying physical memory.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The address environment to be destroyed.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_destroy(FAR arch_addrenv_t *addrenv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_vtext
|
|
*
|
|
* Description:
|
|
* Return the virtual address associated with the newly create .text
|
|
* address environment. This function is used by the binary loaders in
|
|
* order get an address that can be used to initialize the new task.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The representation of the task address environment previously
|
|
* returned by up_addrenv_create.
|
|
* vtext - The location to return the virtual address.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_vtext(FAR arch_addrenv_t *addrenv, FAR void **vtext);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_vdata
|
|
*
|
|
* Description:
|
|
* Return the virtual address associated with the newly create .text
|
|
* address environment. This function is used by the binary loaders in
|
|
* order get an address that can be used to initialize the new task.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The representation of the task address environment previously
|
|
* returned by up_addrenv_create.
|
|
* textsize - For some implementations, the text and data will be saved
|
|
* in the same memory region (read/write/execute) and, in this case,
|
|
* the virtual address of the data just lies at this offset into the
|
|
* common region.
|
|
* vdata - The location to return the virtual address. NOTE that the
|
|
* beginning of the data region is reserved for use by the OS. The
|
|
* returned address will be at a offset from the actual allocated base
|
|
* address to account for the OS private region. The size of that
|
|
* offset is given by ARCH_DATA_RESERVE_SIZE
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_vdata(FAR arch_addrenv_t *addrenv, uintptr_t textsize,
|
|
FAR void **vdata);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_vheap
|
|
*
|
|
* Description:
|
|
* Return the heap virtual address associated with the newly created
|
|
* address environment. This function is used by the binary loaders in
|
|
* order get an address that can be used to initialize the new task.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The representation of the task address environment previously
|
|
* returned by up_addrenv_create.
|
|
* vheap - The location to return the virtual address.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
|
|
int up_addrenv_vheap(FAR const arch_addrenv_t *addrenv, FAR void **vheap);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_heapsize
|
|
*
|
|
* Description:
|
|
* Return the initial heap allocation size. That is the amount of memory
|
|
* allocated by up_addrenv_create() when the heap memory region was first
|
|
* created. This may or may not differ from the heapsize parameter that
|
|
* was passed to up_addrenv_create()
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The representation of the task address environment previously
|
|
* returned by up_addrenv_create.
|
|
*
|
|
* Returned Value:
|
|
* The initial heap size allocated is returned on success; a negated
|
|
* errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
|
|
ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_select
|
|
*
|
|
* Description:
|
|
* After an address environment has been established for a task group (via
|
|
* up_addrenv_create(). This function may be called to instantiate
|
|
* that address environment in the virtual address space. This might be
|
|
* necessary, for example, to load the code for the task group from a file
|
|
* or to access address environment private data.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The representation of the task address environment previously
|
|
* returned by up_addrenv_create.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_select(FAR const arch_addrenv_t *addrenv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_coherent
|
|
*
|
|
* Description:
|
|
* Flush D-Cache and invalidate I-Cache in preparation for a change in
|
|
* address environments. This should immediately precede a call to
|
|
* up_addrenv_select();
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - Describes the address environment to be made coherent.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_coherent(FAR const arch_addrenv_t *addrenv);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_clone
|
|
*
|
|
* Description:
|
|
* Duplicate an address environment. This does not copy the underlying
|
|
* memory, only the representation that can be used to instantiate that
|
|
* memory as an address environment.
|
|
*
|
|
* Input Parameters:
|
|
* src - The address environment to be copied.
|
|
* dest - The location to receive the copied address environment.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_clone(FAR const arch_addrenv_t *src,
|
|
FAR arch_addrenv_t *dest);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_attach
|
|
*
|
|
* Description:
|
|
* This function is called from the core scheduler logic when a thread
|
|
* is created that needs to share the address environment of its task
|
|
* group.
|
|
*
|
|
* Input Parameters:
|
|
* ptcb - The tcb of the parent task.
|
|
* tcb - The tcb of the thread needing the address environment.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_attach(FAR struct tcb_s *ptcb, FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_detach
|
|
*
|
|
* Description:
|
|
* This function is called when a task or thread exits in order to release
|
|
* its reference to an address environment. The address environment,
|
|
* however, should persist until up_addrenv_destroy() is called when the
|
|
* task group is itself destroyed. Any resources unique to this thread
|
|
* may be destroyed now.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the task or thread whose the address environment will
|
|
* be released.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_detach(FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_mprot
|
|
*
|
|
* Description:
|
|
* Modify access rights to an address range.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The address environment to be modified.
|
|
* addr - Base address of the region.
|
|
* len - Size of the region.
|
|
* prot - Access right flags.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
int up_addrenv_mprot(FAR arch_addrenv_t *addrenv, uintptr_t addr,
|
|
size_t len, int prot);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_ustackalloc
|
|
*
|
|
* Description:
|
|
* This function is called when a new thread is created in order to
|
|
* instantiate an address environment for the new thread's stack.
|
|
* up_addrenv_ustackalloc() is essentially the allocator of the physical
|
|
* memory for the new task's stack.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread that requires the stack address environment.
|
|
* stacksize - The size (in bytes) of the initial stack address
|
|
* environment needed by the task. This region may be read/write only.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
|
|
int up_addrenv_ustackalloc(FAR struct tcb_s *tcb, size_t stacksize);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_ustackfree
|
|
*
|
|
* Description:
|
|
* This function is called when any thread exits. This function then
|
|
* destroys the defunct address environment for the thread's stack,
|
|
* releasing the underlying physical memory.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread that no longer requires the stack address
|
|
* environment.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
|
|
int up_addrenv_ustackfree(FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_vustack
|
|
*
|
|
* Description:
|
|
* Return the virtual address associated with the newly create stack
|
|
* address environment.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread with the stack address environment of
|
|
* interest.
|
|
* vstack - The location to return the stack virtual base address.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
|
|
int up_addrenv_vustack(FAR const struct tcb_s *tcb, FAR void **vstack);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_ustackselect
|
|
*
|
|
* Description:
|
|
* After an address environment has been established for a task's stack
|
|
* (via up_addrenv_ustackalloc(). This function may be called to
|
|
* instantiate that address environment in the virtual address space.
|
|
* This is a necessary step before each context switch to the newly created
|
|
* thread (including the initial thread startup).
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread with the stack address environment to be
|
|
* instantiated.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
|
|
int up_addrenv_ustackselect(FAR const struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_kstackalloc
|
|
*
|
|
* Description:
|
|
* This function is called when a new thread is created to allocate
|
|
* the new thread's kernel stack. This function may be called for certain
|
|
* terminating threads which have no kernel stack. It must be tolerant of
|
|
* that case.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread that requires the kernel stack.
|
|
* stacksize - The size (in bytes) of the kernel stack needed by the
|
|
* thread.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_KERNEL_STACK)
|
|
int up_addrenv_kstackalloc(FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_kstackfree
|
|
*
|
|
* Description:
|
|
* This function is called when any thread exits. This function frees
|
|
* the kernel stack.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread that no longer requires the kernel stack.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_KERNEL_STACK)
|
|
int up_addrenv_kstackfree(FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_find_page
|
|
*
|
|
* Description:
|
|
* Find physical page mapped to user virtual address from the address
|
|
* environment page directory.
|
|
*
|
|
* Input Parameters:
|
|
* addrenv - The user address environment.
|
|
* vaddr - The user virtual address
|
|
*
|
|
* Returned Value:
|
|
* Page physical address on success; NULL on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
uintptr_t up_addrenv_find_page(FAR arch_addrenv_t *addrenv, uintptr_t vaddr);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_page_vaddr
|
|
*
|
|
* Description:
|
|
* Find the kernel virtual address associated with physical page.
|
|
*
|
|
* Input Parameters:
|
|
* page - The page physical address.
|
|
*
|
|
* Returned Value:
|
|
* Page kernel virtual address on success; NULL on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
uintptr_t up_addrenv_page_vaddr(uintptr_t page);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_user_vaddr
|
|
*
|
|
* Description:
|
|
* Check if a virtual address is in user virtual address space.
|
|
*
|
|
* Input Parameters:
|
|
* vaddr - The virtual address.
|
|
*
|
|
* Returned Value:
|
|
* True if it is; false if it's not.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
bool up_addrenv_user_vaddr(uintptr_t vaddr);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_page_wipe
|
|
*
|
|
* Description:
|
|
* Wipe a page of physical memory, first mapping it into kernel virtual
|
|
* memory.
|
|
*
|
|
* Input Parameters:
|
|
* page - The page physical address.
|
|
*
|
|
* Returned Value:
|
|
* None.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ADDRENV
|
|
void up_addrenv_page_wipe(uintptr_t page);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_kmap_init
|
|
*
|
|
* Description:
|
|
* Initialize the architecture specific part of the kernel mapping
|
|
* interface.
|
|
*
|
|
* Input Parameters:
|
|
* None.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
* on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_KMAP)
|
|
int up_addrenv_kmap_init(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_kmap_pages
|
|
*
|
|
* Description:
|
|
* Map physical pages into a continuous virtual memory block.
|
|
*
|
|
* Input Parameters:
|
|
* pages - A pointer to the first element in a array of physical address,
|
|
* each corresponding to one page of memory.
|
|
* npages - The number of pages in the list of physical pages to be mapped.
|
|
* vaddr - The virtual address corresponding to the beginning of the
|
|
* (continuous) virtual address region.
|
|
* prot - Access right flags.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
* on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_KMAP)
|
|
int up_addrenv_kmap_pages(FAR void **pages, unsigned int npages,
|
|
uintptr_t vaddr, int prot);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_kunmap_pages
|
|
*
|
|
* Description:
|
|
* Unmap a previously mapped virtual memory region.
|
|
*
|
|
* Input Parameters:
|
|
* vaddr - The virtual address corresponding to the beginning of the
|
|
* (continuous) virtual address region.
|
|
* npages - The number of pages to be unmapped
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
* on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_KMAP)
|
|
int up_addrenv_kunmap_pages(uintptr_t vaddr, unsigned int npages);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_pa_to_va
|
|
*
|
|
* Description:
|
|
* Map phy address to virtual address. Not supported by all architectures.
|
|
*
|
|
* REVISIT: Should this not then be conditional on having that
|
|
* architecture-specific support?
|
|
*
|
|
* Input Parameters:
|
|
* pa - The phy address to be mapped.
|
|
*
|
|
* Returned Value:
|
|
* Virtual address on success; NULL on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
FAR void *up_addrenv_pa_to_va(uintptr_t pa);
|
|
|
|
/****************************************************************************
|
|
* Name: up_addrenv_va_to_pa
|
|
*
|
|
* Description:
|
|
* Map virtual address to phy address. Not supported by all architectures.
|
|
*
|
|
* REVISIT: Should this not then be conditional on having that
|
|
* architecture-specific support?
|
|
*
|
|
* Input Parameters:
|
|
* va - The virtual address to be mapped. Not supported by all
|
|
* architectures.
|
|
*
|
|
* Returned Value:
|
|
* Phy address on success; NULL on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
uintptr_t up_addrenv_va_to_pa(FAR void *va);
|
|
|
|
/****************************************************************************
|
|
* Name: up_shmat
|
|
*
|
|
* Description:
|
|
* Attach, i.e, map, on shared memory region to a user virtual address
|
|
*
|
|
* Input Parameters:
|
|
* pages - A pointer to the first element in a array of physical address,
|
|
* each corresponding to one page of memory.
|
|
* npages - The number of pages in the list of physical pages to be mapped.
|
|
* vaddr - The virtual address corresponding to the beginning of the
|
|
* (contiguous) virtual address region.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
* on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_VMA_MAPPING
|
|
int up_shmat(FAR uintptr_t *pages, unsigned int npages, uintptr_t vaddr);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_shmdt
|
|
*
|
|
* Description:
|
|
* Detach, i.e, unmap, on shared memory region from a user virtual address
|
|
*
|
|
* Input Parameters:
|
|
* vaddr - The virtual address corresponding to the beginning of the
|
|
* (contiguous) virtual address region.
|
|
* npages - The number of pages to be unmapped
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned
|
|
* on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_VMA_MAPPING
|
|
int up_shmdt(uintptr_t vaddr, unsigned int npages);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Interfaces required for ELF module support
|
|
*
|
|
* up_checkarch - Perform architecture-specific ELF check
|
|
* up_relocate - Perform architecture-specific ELF relocation
|
|
* up_relocateadd - Perform architecture-specific ELF relocation
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* See prototype in include/nuttx/elf.h */
|
|
|
|
/****************************************************************************
|
|
* Name: up_irqinitialize
|
|
****************************************************************************/
|
|
|
|
void up_irqinitialize(void);
|
|
|
|
/****************************************************************************
|
|
* Name: up_enable_irq
|
|
*
|
|
* Description:
|
|
* On many architectures, there are three levels of interrupt enabling: (1)
|
|
* at the global level, (2) at the level of the interrupt controller,
|
|
* and (3) at the device level. In order to receive interrupts, they
|
|
* must be enabled at all three levels.
|
|
*
|
|
* This function implements enabling of the device specified by 'irq'
|
|
* at the interrupt controller level if supported by the architecture
|
|
* (up_irq_restore() supports the global level, the device level is
|
|
* hardware specific).
|
|
*
|
|
* Since this API is not supported on all architectures, it should be
|
|
* avoided in common implementations where possible.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_ARCH_NOINTC
|
|
void up_enable_irq(int irq);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_disable_irq
|
|
*
|
|
* Description:
|
|
* This function implements disabling of the device specified by 'irq'
|
|
* at the interrupt controller level if supported by the architecture
|
|
* (up_irq_save() supports the global level, the device level is hardware
|
|
* specific).
|
|
*
|
|
* Since this API is not supported on all architectures, it should be
|
|
* avoided in common implementations where possible.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_ARCH_NOINTC
|
|
void up_disable_irq(int irq);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_affinity_irq
|
|
*
|
|
* Description:
|
|
* Set an IRQ affinity by software.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SMP
|
|
void up_affinity_irq(int irq, cpu_set_t cpuset);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_trigger_irq
|
|
*
|
|
* Description:
|
|
* Trigger an IRQ by software. May not be supported by all architectures.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_IRQTRIGGER
|
|
void up_trigger_irq(int irq, cpu_set_t cpuset);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_prioritize_irq
|
|
*
|
|
* Description:
|
|
* Set the priority of an IRQ.
|
|
*
|
|
* Since this API is not supported on all architectures, it should be
|
|
* avoided in common implementations where possible.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_IRQPRIO
|
|
int up_prioritize_irq(int irq, int priority);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_secure_irq
|
|
*
|
|
* Description:
|
|
* Secure an IRQ
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_TRUSTZONE_SECURE) || defined(CONFIG_ARCH_HIPRI_INTERRUPT)
|
|
void up_secure_irq(int irq, bool secure);
|
|
#else
|
|
# define up_secure_irq(i, s)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_secure_irq_all
|
|
*
|
|
* Description:
|
|
* Secure all IRQ
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_ARCH_TRUSTZONE_SECURE) || defined(CONFIG_ARCH_HIPRI_INTERRUPT)
|
|
void up_secure_irq_all(bool secure);
|
|
#else
|
|
# define up_secure_irq_all(s)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Function: up_adjtime
|
|
*
|
|
* Description:
|
|
* Adjusts timer period. This call is used when adjusting timer period as
|
|
* defined in adjtime() function.
|
|
*
|
|
* Input Parameters:
|
|
* ppb - Adjustment in parts per billion (nanoseconds per second).
|
|
* Zero is default rate, positive value makes clock run faster
|
|
* and negative value slower.
|
|
*
|
|
* Assumptions:
|
|
* Called from within critical section or interrupt context.
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_ADJTIME
|
|
void up_adjtime(long ppb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Function: up_timer_initialize
|
|
*
|
|
* Description:
|
|
* This function is called during start-up to initialize
|
|
* the timer hardware.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_timer_initialize(void);
|
|
|
|
/****************************************************************************
|
|
* Tickless OS Support.
|
|
*
|
|
* When CONFIG_SCHED_TICKLESS is enabled, all support for timer interrupts
|
|
* is suppressed and the platform specific code is expected to provide the
|
|
* following custom functions.
|
|
*
|
|
* Architecture specific timer initialization logic initializes the timer
|
|
* facilities. This happens early in the initialization sequence (via
|
|
* up_initialize()).
|
|
* int up_timer_gettime(FAR struct timespec *ts): Returns the current
|
|
* time from the platform specific time source.
|
|
*
|
|
* The tickless option can be supported either via a simple interval timer
|
|
* (plus elapsed time) or via an alarm. The interval timer allows
|
|
* programming events to occur after an interval. With the alarm, you can
|
|
* set a time in the future and get an event when that alarm goes off.
|
|
*
|
|
* int up_alarm_cancel(void): Cancel the alarm.
|
|
* int up_alarm_start(FAR const struct timespec *ts): Enable (or re-enable
|
|
* the alarm.
|
|
* #else
|
|
* int up_timer_cancel(void): Cancels the interval timer.
|
|
* int up_timer_start(FAR const struct timespec *ts): Start (or re-starts)
|
|
* the interval timer.
|
|
* #endif
|
|
*
|
|
* The RTOS will provide the following interfaces for use by the platform-
|
|
* specific interval timer implementation:
|
|
*
|
|
* #ifdef CONFIG_SCHED_TICKLESS_ALARM
|
|
* void nxsched_alarm_expiration(FAR const struct timespec *ts): Called
|
|
* by the platform-specific logic when the alarm expires.
|
|
* #else
|
|
* void nxsched_timer_expiration(void): Called by the platform-specific
|
|
* logic when the interval timer expires.
|
|
* #endif
|
|
*
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_timer_gettime
|
|
*
|
|
* Description:
|
|
* Return the elapsed time since power-up (or, more correctly, since
|
|
* the architecture-specific timer was initialized). This function is
|
|
* functionally equivalent to:
|
|
*
|
|
* int clock_gettime(clockid_t clockid, FAR struct timespec *ts);
|
|
*
|
|
* when clockid is CLOCK_MONOTONIC.
|
|
*
|
|
* This function provides the basis for reporting the current time and
|
|
* also is used to eliminate error build-up from small errors in interval
|
|
* time calculations.
|
|
*
|
|
* Provided by platform-specific code and called from the RTOS base code.
|
|
*
|
|
* Input Parameters:
|
|
* ts - Provides the location in which to return the up-time.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
|
* any failure.
|
|
*
|
|
* Assumptions:
|
|
* Called from the normal tasking context. The implementation must
|
|
* provide whatever mutual exclusion is necessary for correct operation.
|
|
* This can include disabling interrupts in order to assure atomic register
|
|
* operations.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_timer_gettime(FAR struct timespec *ts);
|
|
int up_timer_gettick(FAR clock_t *ticks);
|
|
void up_timer_getmask(FAR clock_t *mask);
|
|
|
|
/****************************************************************************
|
|
* Name: up_alarm_cancel
|
|
*
|
|
* Description:
|
|
* Cancel the alarm and return the time of cancellation of the alarm.
|
|
* These two steps need to be as nearly atomic as possible.
|
|
* nxsched_alarm_expiration() will not be called unless the alarm is
|
|
* restarted with up_alarm_start().
|
|
*
|
|
* If, as a race condition, the alarm has already expired when this
|
|
* function is called, then time returned is the current time.
|
|
*
|
|
* NOTE: This function may execute at a high rate with no timer running (as
|
|
* when pre-emption is enabled and disabled).
|
|
*
|
|
* Provided by platform-specific code and called from the RTOS base code.
|
|
*
|
|
* Input Parameters:
|
|
* ts - Location to return the expiration time. The current time should
|
|
* returned if the alarm is not active. ts may be NULL in which
|
|
* case the time is not returned.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success. A call to up_alarm_cancel() when
|
|
* the timer is not active should also return success; a negated errno
|
|
* value is returned on any failure.
|
|
*
|
|
* Assumptions:
|
|
* May be called from interrupt level handling or from the normal tasking
|
|
* level. Interrupts may need to be disabled internally to assure
|
|
* non-reentrancy.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
|
int up_alarm_cancel(FAR struct timespec *ts);
|
|
# else
|
|
int up_alarm_tick_cancel(FAR clock_t *ticks);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_alarm_start
|
|
*
|
|
* Description:
|
|
* Start the alarm. nxsched_alarm_expiration() will be called when the
|
|
* alarm occurs (unless up_alaram_cancel is called to stop it).
|
|
*
|
|
* Provided by platform-specific code and called from the RTOS base code.
|
|
*
|
|
* Input Parameters:
|
|
* ts - The time in the future at the alarm is expected to occur. When
|
|
* the alarm occurs the timer logic will call
|
|
* nxsched_alarm_expiration().
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
|
* any failure.
|
|
*
|
|
* Assumptions:
|
|
* May be called from interrupt level handling or from the normal tasking
|
|
* level. Interrupts may need to be disabled internally to assure
|
|
* non-reentrancy.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
|
int up_alarm_start(FAR const struct timespec *ts);
|
|
# else
|
|
int up_alarm_tick_start(clock_t ticks);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_timer_cancel
|
|
*
|
|
* Description:
|
|
* Cancel the interval timer and return the time remaining on the timer.
|
|
* These two steps need to be as nearly atomic as possible.
|
|
* nxsched_timer_expiration() will not be called unless the timer is
|
|
* restarted with up_timer_start().
|
|
*
|
|
* If, as a race condition, the timer has already expired when this
|
|
* function is called, then that pending interrupt must be cleared so
|
|
* that up_timer_start() and the remaining time of zero should be
|
|
* returned.
|
|
*
|
|
* NOTE: This function may execute at a high rate with no timer running (as
|
|
* when pre-emption is enabled and disabled).
|
|
*
|
|
* Provided by platform-specific code and called from the RTOS base code.
|
|
*
|
|
* Input Parameters:
|
|
* ts - Location to return the remaining time. Zero should be returned
|
|
* if the timer is not active. ts may be zero in which case the
|
|
* time remaining is not returned.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success. A call to up_timer_cancel() when
|
|
* the timer is not active should also return success; a negated errno
|
|
* value is returned on any failure.
|
|
*
|
|
* Assumptions:
|
|
* May be called from interrupt level handling or from the normal tasking
|
|
* level. Interrupts may need to be disabled internally to assure
|
|
* non-reentrancy.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
|
int up_timer_cancel(FAR struct timespec *ts);
|
|
# else
|
|
int up_timer_tick_cancel(FAR clock_t *ticks);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_timer_start
|
|
*
|
|
* Description:
|
|
* Start the interval timer. nxsched_timer_expiration() will be called at
|
|
* the completion of the timeout (unless up_timer_cancel is called to stop
|
|
* the timing.
|
|
*
|
|
* Provided by platform-specific code and called from the RTOS base code.
|
|
*
|
|
* Input Parameters:
|
|
* ts - Provides the time interval until nxsched_timer_expiration() is
|
|
* called.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) is returned on success; a negated errno value is returned on
|
|
* any failure.
|
|
*
|
|
* Assumptions:
|
|
* May be called from interrupt level handling or from the normal tasking
|
|
* level. Interrupts may need to be disabled internally to assure
|
|
* non-reentrancy.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
# ifndef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
|
|
int up_timer_start(FAR const struct timespec *ts);
|
|
# else
|
|
int up_timer_tick_start(clock_t ticks);
|
|
# endif
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_getsp
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* Current stack pointer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* uintptr_t up_getsp(void);
|
|
*
|
|
* The actual declaration or definition is provided in arch/arch.h.
|
|
* The actual implementation may be a MACRO or an inline function.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
* Name: up_getusrsp
|
|
*
|
|
* Input Parameters:
|
|
* regs - regs to get sp
|
|
*
|
|
* Returned Value:
|
|
* User stack pointer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* static inline_function uintptr_t up_getusrsp(void *regs);
|
|
* The actual implementation should be provided in irq.h per arch.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
* TLS support
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_tls_info
|
|
*
|
|
* Description:
|
|
* Return the TLS information structure for the currently executing thread.
|
|
* When TLS is enabled, up_create_stack() will align allocated stacks to
|
|
* the TLS_STACK_ALIGN value. An instance of the following structure will
|
|
* be implicitly positioned at the "lower" end of the stack. Assuming a
|
|
* "push down" stack, this is at the "far" end of the stack (and can be
|
|
* clobbered if the stack overflows).
|
|
*
|
|
* If an MCU has a "push up" then that TLS structure will lie at the top
|
|
* of the stack and stack allocation and initialization logic must take
|
|
* care to preserve this structure content.
|
|
*
|
|
* The stack memory is fully accessible to user mode threads.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* A pointer to TLS info structure at the beginning of the STACK memory
|
|
* allocation. This is essentially an application of the TLS_INFO(sp)
|
|
* macro and has a platform dependency only in the manner in which the
|
|
* stack pointer (sp) is obtained and interpreted.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* struct tls_info_s;
|
|
* FAR struct tls_info_s *up_tls_info(void);
|
|
*
|
|
* The actual definition is provided in arch/arch.h as a macro. The default
|
|
* implementation provided here assume the arch has a "push down" stack.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
* Name: up_tls_size
|
|
*
|
|
* Description:
|
|
* Get TLS (sizeof(struct tls_info_s) + tdata + tbss) section size.
|
|
*
|
|
* Returned Value:
|
|
* Size of (sizeof(struct tls_info_s) + tdata + tbss).
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
|
int up_tls_size(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_tls_initialize
|
|
*
|
|
* Description:
|
|
* Initialize thread local region
|
|
*
|
|
* Input Parameters:
|
|
* tls_data - The memory region to initialize
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SCHED_THREAD_LOCAL
|
|
struct tls_info_s;
|
|
void up_tls_initialize(FAR struct tls_info_s *info);
|
|
#else
|
|
#define up_tls_initialize(x)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Multiple CPU support
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_testset
|
|
*
|
|
* Description:
|
|
* Perform an atomic test and set operation on the provided spinlock.
|
|
*
|
|
* Input Parameters:
|
|
* lock - The address of spinlock object.
|
|
*
|
|
* Returned Value:
|
|
* The spinlock is always locked upon return. The value of previous value
|
|
* of the spinlock variable is returned, either SP_LOCKED if the spinlock
|
|
* was previously locked (meaning that the test-and-set operation failed to
|
|
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
|
|
* (meaning that we successfully obtained the lock)
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* See prototype in include/nuttx/spinlock.h */
|
|
|
|
/****************************************************************************
|
|
* Name: up_fetchadd8, up_fetchadd16, and up_fetchadd32
|
|
*
|
|
* Description:
|
|
* Perform an atomic fetch add operation on the provided 8-, 16-, or 32-
|
|
* bit value.
|
|
*
|
|
* This function must be provided via the architecture-specific logic.
|
|
*
|
|
* Input Parameters:
|
|
* addr - The address of value to be incremented.
|
|
* value - The addend
|
|
*
|
|
* Returned Value:
|
|
* The incremented value (volatile!)
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_FETCHADD
|
|
int32_t up_fetchadd32(FAR volatile int32_t *addr, int32_t value);
|
|
int16_t up_fetchadd16(FAR volatile int16_t *addr, int16_t value);
|
|
int8_t up_fetchadd8(FAR volatile int8_t *addr, int8_t value);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_fetchsub8
|
|
*
|
|
* Description:
|
|
* Perform an atomic fetch subtract operation on the provided 8-, 16-, or
|
|
* 32-bit value.
|
|
*
|
|
* This function must be provided via the architecture-specific logic.
|
|
*
|
|
* Input Parameters:
|
|
* addr - The address of value to be decremented.
|
|
* value - The subtrahend
|
|
*
|
|
* Returned Value:
|
|
* The decremented value (volatile!)
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_FETCHADD
|
|
int32_t up_fetchsub32(FAR volatile int32_t *addr, int32_t value);
|
|
int16_t up_fetchsub16(FAR volatile int16_t *addr, int16_t value);
|
|
int8_t up_fetchsub8(FAR volatile int8_t *addr, int8_t value);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_cpu_idlestack
|
|
*
|
|
* Description:
|
|
* Allocate a stack for the CPU[n] IDLE task (n > 0) if appropriate and
|
|
* setup up stack-related information in the IDLE task's TCB. This
|
|
* function is always called before up_cpu_start(). This function is
|
|
* only called for the CPU's initial IDLE task; up_create_task is used for
|
|
* all normal tasks, pthreads, and kernel threads for all CPUs.
|
|
*
|
|
* The initial IDLE task is a special case because the CPUs can be started
|
|
* in different wans in different environments:
|
|
*
|
|
* 1. The CPU may already have been started and waiting in a low power
|
|
* state for up_cpu_start(). In this case, the IDLE thread's stack
|
|
* has already been allocated and is already in use. Here
|
|
* up_cpu_idlestack() only has to provide information about the
|
|
* already allocated stack.
|
|
*
|
|
* 2. The CPU may be disabled but started when up_cpu_start() is called.
|
|
* In this case, a new stack will need to be created for the IDLE
|
|
* thread and this function is then equivalent to:
|
|
*
|
|
* return up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL);
|
|
*
|
|
* The following TCB fields must be initialized by this function:
|
|
*
|
|
* - adj_stack_size: Stack size after adjustment for hardware, processor,
|
|
* etc. This value is retained only for debug purposes.
|
|
* - stack_alloc_ptr: Pointer to allocated stack
|
|
* - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
|
|
* Arguments has been removed from the stack allocation.
|
|
*
|
|
* Input Parameters:
|
|
* - cpu: CPU index that indicates which CPU the IDLE task is
|
|
* being created for.
|
|
* - tcb: The TCB of new CPU IDLE task
|
|
* - stack_size: The requested stack size for the IDLE task. At least
|
|
* this much must be allocated. This should be
|
|
* CONFIG_IDLETHREAD_STACKSIZE.
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size);
|
|
|
|
/****************************************************************************
|
|
* Name: up_cpu_start
|
|
*
|
|
* Description:
|
|
* In an SMP configuration, only one CPU is initially active (CPU 0).
|
|
* System initialization occurs on that single thread. At the completion of
|
|
* the initialization of the OS, just before beginning normal multitasking,
|
|
* the additional CPUs would be started by calling this function.
|
|
*
|
|
* Each CPU is provided the entry point to its IDLE task when started. A
|
|
* TCB for each CPU's IDLE task has been initialized and placed in the
|
|
* CPU's g_assignedtasks[cpu] list. No stack has been allocated or
|
|
* initialized.
|
|
*
|
|
* The OS initialization logic calls this function repeatedly until each
|
|
* CPU has been started, 1 through (CONFIG_SMP_NCPUS-1).
|
|
*
|
|
* Input Parameters:
|
|
* cpu - The index of the CPU being started. This will be a numeric
|
|
* value in the range of one to (CONFIG_SMP_NCPUS-1).
|
|
* (CPU 0 is already active)
|
|
*
|
|
* Returned Value:
|
|
* Zero on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SMP
|
|
int up_cpu_start(int cpu);
|
|
#endif
|
|
|
|
#ifdef CONFIG_SMP
|
|
/****************************************************************************
|
|
* Name: up_send_smp_sched
|
|
*
|
|
* Description:
|
|
* pause task execution on the CPU
|
|
* check whether there are tasks delivered to specified cpu
|
|
* and try to run them.
|
|
*
|
|
* Input Parameters:
|
|
* cpu - The index of the CPU to be paused.
|
|
*
|
|
* Returned Value:
|
|
* Zero on success; a negated errno value on failure.
|
|
*
|
|
* Assumptions:
|
|
* Called from within a critical section;
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_send_smp_sched(int cpu);
|
|
|
|
/****************************************************************************
|
|
* Name: up_send_smp_call
|
|
*
|
|
* Description:
|
|
* Send smp call to target cpu
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_send_smp_call(cpu_set_t cpuset);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_romgetc
|
|
*
|
|
* Description:
|
|
* In Harvard architectures, data accesses and instruction accesses occur
|
|
* on different buses, perhaps concurrently. All data accesses are
|
|
* performed on the data bus unless special machine instructions are
|
|
* used to read data from the instruction address space. Also, in the
|
|
* typical MCU, the available SRAM data memory is much smaller that the
|
|
* non-volatile FLASH instruction memory. So if the application requires
|
|
* many constant strings, the only practical solution may be to store
|
|
* those constant strings in FLASH memory where they can only be accessed
|
|
* using architecture-specific machine instructions.
|
|
*
|
|
* A similar case is where strings are retained in "external" memory such
|
|
* as EEPROM or serial FLASH. This case is similar only in that again
|
|
* special operations are required to obtain the string data; it cannot
|
|
* be accessed directly from a string pointer.
|
|
*
|
|
* If CONFIG_ARCH_ROMGETC is defined, then the architecture logic must
|
|
* export the function up_romgetc(). up_romgetc() will simply read one
|
|
* byte of data from the instruction space.
|
|
*
|
|
* If CONFIG_ARCH_ROMGETC, certain C stdio functions are effected: (1)
|
|
* All format strings in printf, fprintf, sprintf, etc. are assumed to
|
|
* lie in FLASH (string arguments for %s are still assumed to reside in
|
|
* SRAM). And (2), the string argument to puts and fputs is assumed to
|
|
* reside in FLASH. Clearly, these assumptions may have to modified for
|
|
* the particular needs of your environment. There is no
|
|
* "one-size-fits-all" solution for this problem.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_ROMGETC
|
|
char up_romgetc(FAR const char *ptr);
|
|
#else
|
|
# define up_romgetc(ptr) (*ptr)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_mdelay and up_udelay
|
|
*
|
|
* Description:
|
|
* Some device drivers may require that the platform-specific logic
|
|
* provides these timing loops for short delays.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_mdelay(unsigned int milliseconds);
|
|
void up_udelay(useconds_t microseconds);
|
|
void up_ndelay(unsigned long nanoseconds);
|
|
|
|
/****************************************************************************
|
|
* These are standard interfaces that are exported by the OS for use by the
|
|
* architecture specific logic.
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: nxsched_process_timer
|
|
*
|
|
* Description:
|
|
* This function handles system timer events (only when
|
|
* CONFIG_SCHED_TICKLESS is *not* defined). The timer interrupt logic
|
|
* itself is implemented in the architecture specific code, but must call
|
|
* the following OS function periodically -- the calling interval must
|
|
* be CONFIG_USEC_PER_TICK.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_SCHED_TICKLESS
|
|
void nxsched_process_timer(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: nxsched_timer_expiration
|
|
*
|
|
* Description:
|
|
* If CONFIG_SCHED_TICKLESS is defined, then this function is provided by
|
|
* the RTOS base code and called from platform-specific code when the
|
|
* interval timer used to implement the tick-less OS expires.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
* Assumptions/Limitations:
|
|
* Base code implementation assumes that this function is called from
|
|
* interrupt handling logic with interrupts disabled.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
void nxsched_timer_expiration(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: nxsched_alarm_expiration
|
|
*
|
|
* Description:
|
|
* if CONFIG_SCHED_TICKLESS is defined, then this function is provided by
|
|
* the RTOS base code and called from platform-specific code when the
|
|
* alarm used to implement the tick-less OS expires.
|
|
*
|
|
* Input Parameters:
|
|
* ts - The time that the alarm expired
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
* Assumptions/Limitations:
|
|
* Base code implementation assumes that this function is called from
|
|
* interrupt handling logic with interrupts disabled.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)
|
|
void nxsched_alarm_expiration(FAR const struct timespec *ts);
|
|
void nxsched_alarm_tick_expiration(clock_t ticks);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: nxsched_get_next_expired
|
|
*
|
|
* Description:
|
|
* Get the time remaining until the next timer expiration.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* The time remaining until the next timer expiration.
|
|
*
|
|
****************************************************************************/
|
|
|
|
clock_t nxsched_get_next_expired(void);
|
|
|
|
/****************************************************************************
|
|
* Name: nxsched_process_cpuload_ticks
|
|
*
|
|
* Description:
|
|
* Collect data that can be used for CPU load measurements. When
|
|
* CONFIG_SCHED_CPULOAD_EXTCLK is defined, this is an exported interface,
|
|
* use the the external clock logic. Otherwise, it is an OS internal
|
|
* interface.
|
|
*
|
|
* Input Parameters:
|
|
* ticks - The ticks that we increment in this cpuload
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
* Assumptions/Limitations:
|
|
* This function is called from a timer interrupt handler with all
|
|
* interrupts disabled.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SCHED_CPULOAD_EXTCLK
|
|
void nxsched_process_cpuload_ticks(clock_t ticks);
|
|
# define nxsched_process_cpuload() nxsched_process_cpuload_ticks(1)
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: irq_dispatch
|
|
*
|
|
* Description:
|
|
* This function must be called from the architecture-specific logic in
|
|
* order to dispatch an interrupt to the appropriate, registered handling
|
|
* logic.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void irq_dispatch(int irq, FAR void *context);
|
|
|
|
/****************************************************************************
|
|
* Name: up_check_tcbstack and friends
|
|
*
|
|
* Description:
|
|
* Determine (approximately) how much stack has been used be searching the
|
|
* stack memory for a high water mark. That is, the deepest level of the
|
|
* stack that clobbered some recognizable marker in the stack memory.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* The estimated amount of stack space used.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_STACK_COLORATION
|
|
struct tcb_s;
|
|
size_t up_check_tcbstack(FAR struct tcb_s *tcb);
|
|
#if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
|
size_t up_check_intstack(int cpu);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(CONFIG_ARCH_INTERRUPTSTACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
|
uintptr_t up_get_intstackbase(int cpu);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_initialize
|
|
*
|
|
* Description:
|
|
* Initialize the builtin, MCU hardware RTC per the selected
|
|
* configuration. This function is called once very early in the OS
|
|
* initialization sequence.
|
|
*
|
|
* NOTE that initialization of external RTC hardware that depends on the
|
|
* availability of OS resources (such as SPI or I2C) must be deferred
|
|
* until the system has fully booted. Other, RTC-specific initialization
|
|
* functions are used in that case.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno on failure
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC)
|
|
int up_rtc_initialize(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_time
|
|
*
|
|
* Description:
|
|
* Get the current time in seconds. This is similar to the standard time()
|
|
* function. This interface is only required if the low-resolution
|
|
* RTC/counter hardware implementation is selected. It is only used by the
|
|
* RTOS during initialization to set up the system time when CONFIG_RTC is
|
|
* set but neither CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set.
|
|
*
|
|
* Input Parameters:
|
|
* None
|
|
*
|
|
* Returned Value:
|
|
* The current time in seconds.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC) && !defined(CONFIG_RTC_HIRES)
|
|
time_t up_rtc_time(void);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_gettime
|
|
*
|
|
* Description:
|
|
* Get the current time from the high resolution RTC clock/counter. This
|
|
* interface is only supported by the high-resolution RTC/counter hardware
|
|
* implementation.
|
|
* It is used to replace the system timer.
|
|
*
|
|
* Input Parameters:
|
|
* tp - The location to return the high resolution time value.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC) && defined(CONFIG_RTC_HIRES)
|
|
int up_rtc_gettime(FAR struct timespec *tp);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_getdatetime
|
|
*
|
|
* Description:
|
|
* Get the current date and time from the date/time RTC. This interface
|
|
* is only supported by the date/time RTC hardware implementation.
|
|
* It is used to replace the system timer. It is only used by the RTOS
|
|
* during initialization to set up the system time when CONFIG_RTC and
|
|
* CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
|
|
*
|
|
* NOTE: Some date/time RTC hardware is capability of sub-second accuracy.
|
|
* That sub-second accuracy is lost in this interface. However, since the
|
|
* system time is reinitialized on each power-up/reset, there will be no
|
|
* timing inaccuracy in the long run.
|
|
*
|
|
* Input Parameters:
|
|
* tp - The location to return the high resolution time value.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME)
|
|
int up_rtc_getdatetime(FAR struct tm *tp);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_getdatetime_with_subseconds
|
|
*
|
|
* Description:
|
|
* Get the current date and time from the date/time RTC. This interface
|
|
* is only supported by the date/time RTC hardware implementation.
|
|
* It is used to replace the system timer. It is only used by the RTOS
|
|
* during initialization to set up the system time when CONFIG_RTC and
|
|
* CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
|
|
*
|
|
* NOTE: This interface exposes sub-second accuracy capability of RTC
|
|
* hardware. This interface allow maintaining timing accuracy when system
|
|
* time needs constant resynchronization with RTC, for example on MCU with
|
|
* low-power state that stop system timer.
|
|
*
|
|
* Input Parameters:
|
|
* tp - The location to return the high resolution time value.
|
|
* nsec - The location to return the subsecond time value.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno on failure
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME) && \
|
|
defined(CONFIG_ARCH_HAVE_RTC_SUBSECONDS)
|
|
int up_rtc_getdatetime_with_subseconds(FAR struct tm *tp, FAR long *nsec);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_settime
|
|
*
|
|
* Description:
|
|
* Set the RTC to the provided time. All RTC implementations must be able
|
|
* to set their time based on a standard timespec.
|
|
*
|
|
* Input Parameters:
|
|
* tp - the time to use
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_RTC
|
|
int up_rtc_settime(FAR const struct timespec *tp);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_rtc_adjtime
|
|
*
|
|
* Description:
|
|
* Adjust RTC frequency (running rate). Used by adjtime() when RTC is used
|
|
* as system time source.
|
|
*
|
|
* Input Parameters:
|
|
* ppb - Adjustment in parts per billion (nanoseconds per second).
|
|
* Zero is default rate, positive value makes clock run faster
|
|
* and negative value slower.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) on success; a negated errno value on failure.
|
|
*
|
|
* Assumptions:
|
|
* Called from within a critical section.
|
|
****************************************************************************/
|
|
|
|
#if defined(CONFIG_RTC_HIRES) && defined(CONFIG_RTC_ADJTIME)
|
|
int up_rtc_adjtime(long ppb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: arch_phy_irq
|
|
*
|
|
* Description:
|
|
* This function may be called to register an interrupt handler that will
|
|
* be called when a PHY interrupt occurs. This function both attaches
|
|
* the interrupt handler and enables the interrupt if 'handler' is non-
|
|
* NULL. If handler is NULL, then the interrupt is detached and disabled
|
|
* instead.
|
|
*
|
|
* The PHY interrupt is always disabled upon return. The caller must
|
|
* call back through the enable function point to control the state of
|
|
* the interrupt.
|
|
*
|
|
* This interrupt may or may not be available on a given platform depending
|
|
* on how the network hardware architecture is implemented. In a typical
|
|
* case, the PHY interrupt is provided to board-level logic as a GPIO
|
|
* interrupt (in which case this is a board-specific interface and really
|
|
* should be called board_phy_irq()); In other cases, the PHY interrupt
|
|
* may be cause by the chip's MAC logic (in which case arch_phy_irq()) is
|
|
* an appropriate name. Other other boards, there may be no PHY interrupts
|
|
* available at all. If client attachable PHY interrupts are available
|
|
* from the board or from the chip, then CONFIG_ARCH_PHY_INTERRUPT should
|
|
* be defined to indicate that fact.
|
|
*
|
|
* Typical usage:
|
|
* a. OS service logic (not application logic*) attaches to the PHY
|
|
* PHY interrupt and enables the PHY interrupt.
|
|
* b. When the PHY interrupt occurs: (1) the interrupt should be
|
|
* disabled and () work should be scheduled on the worker thread (or
|
|
* perhaps a dedicated application thread).
|
|
* c. That worker thread should use the SIOCGMIIPHY, SIOCGMIIREG,
|
|
* and SIOCSMIIREG ioctl calls** to communicate with the PHY,
|
|
* determine what network event took place (Link Up/Down?), and
|
|
* take the appropriate actions.
|
|
* d. It should then interact the PHY to clear any pending
|
|
* interrupts, then re-enable the PHY interrupt.
|
|
*
|
|
* * This is an OS internal interface and should not be used from
|
|
* application space. Rather applications should use the SIOCMIISIG
|
|
* ioctl to receive a signal when a PHY event occurs.
|
|
* ** This interrupt is really of no use if the Ethernet MAC driver
|
|
* does not support these ioctl calls.
|
|
*
|
|
* Input Parameters:
|
|
* intf - Identifies the network interface. For example "eth0". Only
|
|
* useful on platforms that support multiple Ethernet interfaces
|
|
* and, hence, multiple PHYs and PHY interrupts.
|
|
* handler - The client interrupt handler to be invoked when the PHY
|
|
* asserts an interrupt. Must reside in OS space, but can
|
|
* signal tasks in user space. A value of NULL can be passed
|
|
* in order to detach and disable the PHY interrupt.
|
|
* arg - The argument that will accompany the interrupt
|
|
* enable - A function pointer that be unused to enable or disable the
|
|
* PHY interrupt.
|
|
*
|
|
* Returned Value:
|
|
* Zero (OK) returned on success; a negated errno value is returned on
|
|
* failure.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_PHY_INTERRUPT
|
|
int arch_phy_irq(FAR const char *intf, xcpt_t handler, void *arg,
|
|
phy_enable_t *enable);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Debug interfaces exported by the architecture-specific logic
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: up_putc
|
|
*
|
|
* Description:
|
|
* Output one character on the console
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_putc(int ch);
|
|
|
|
/****************************************************************************
|
|
* Name: up_lowputc
|
|
*
|
|
* Description:
|
|
* Output one character in early boot-stages.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_LOWPUTC
|
|
void up_lowputc(int ch);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_puts
|
|
*
|
|
* Description:
|
|
* Output a string on the console
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define up_puts(str) up_nputs(str, ~((size_t)0))
|
|
void up_nputs(FAR const char *str, size_t len);
|
|
|
|
/****************************************************************************
|
|
* Name: arch_sporadic_*
|
|
*
|
|
* Description:
|
|
* Hooks that can be enabled to monitor the behavior of the sporadic
|
|
* scheduler. These are call outs from the OS and must be provided by
|
|
* architecture-specific logic.
|
|
*
|
|
* Input Parameters:
|
|
* tcb - The TCB of the thread to be restarted.
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_SPORADIC_INSTRUMENTATION
|
|
void arch_sporadic_start(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_lowpriority(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_suspend(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_resume(FAR struct tcb_s *tcb);
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_perf_*
|
|
*
|
|
* Description:
|
|
* The first interface simply provides the current time value in unknown
|
|
* units. NOTE: This function may be called early before the timer has
|
|
* been initialized. In that event, the function should just return a
|
|
* start time of zero.
|
|
*
|
|
* Nothing is assumed about the units of this time value. The following
|
|
* are assumed, however: (1) The time is an unsigned integer value, (2)
|
|
* the time is monotonically increasing, and (3) the elapsed time (also
|
|
* in unknown units) can be obtained by subtracting a start time from
|
|
* the current time.
|
|
*
|
|
* The second interface simple converts an elapsed time into well known
|
|
* units.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_perf_init(FAR void *arg);
|
|
clock_t up_perf_gettime(void);
|
|
unsigned long up_perf_getfreq(void);
|
|
void up_perf_convert(clock_t elapsed, FAR struct timespec *ts);
|
|
|
|
/****************************************************************************
|
|
* Name: up_show_cpuinfo
|
|
*
|
|
* Description:
|
|
* This function will be called when reading /proc/cpufinfo.
|
|
* This function should be implemented by each arch to show its cpuinfo.
|
|
*
|
|
* Input Parameters:
|
|
* buf - The address of the user's receive buffer.
|
|
* buf_size - The size (in bytes) of the user's receive buffer.
|
|
* file_off - The /proc/cpuinfo file offset.
|
|
*
|
|
* Returned Value:
|
|
* The number of bytes actually transferred into the user's receive buffer.
|
|
*
|
|
****************************************************************************/
|
|
|
|
ssize_t up_show_cpuinfo(FAR char *buf, size_t buf_size, off_t file_off);
|
|
|
|
/****************************************************************************
|
|
* Name: up_saveusercontext
|
|
*
|
|
* Description:
|
|
* Save the current thread context
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_saveusercontext(FAR void *saveregs);
|
|
|
|
/****************************************************************************
|
|
* Name: up_fpucmp
|
|
*
|
|
* Description:
|
|
* Compare FPU areas from thread context.
|
|
*
|
|
* Input Parameters:
|
|
* saveregs1 - Pointer to the saved FPU registers.
|
|
* saveregs2 - Pointer to the saved FPU registers.
|
|
*
|
|
* Returned Value:
|
|
* True if FPU areas compare equal, False otherwise.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_ARCH_FPU
|
|
bool up_fpucmp(FAR const void *saveregs1, FAR const void *saveregs2);
|
|
#else
|
|
#define up_fpucmp(r1, r2) (true)
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_DEBUG
|
|
|
|
/****************************************************************************
|
|
* Name: up_debugpoint_add
|
|
*
|
|
* Description:
|
|
* Add a debugpoint.
|
|
*
|
|
* Input Parameters:
|
|
* type - The debugpoint type. optional value:
|
|
* DEBUGPOINT_WATCHPOINT_RO - Read only watchpoint.
|
|
* DEBUGPOINT_WATCHPOINT_WO - Write only watchpoint.
|
|
* DEBUGPOINT_WATCHPOINT_RW - Read and write watchpoint.
|
|
* DEBUGPOINT_BREAKPOINT - Breakpoint.
|
|
* DEBUGPOINT_STEPPOINT - Single step.
|
|
* addr - The address to be debugged.
|
|
* size - The watchpoint size. only for watchpoint.
|
|
* callback - The callback function when debugpoint triggered.
|
|
* if NULL, the debugpoint will be removed.
|
|
* arg - The argument of callback function.
|
|
*
|
|
* Returned Value:
|
|
* Zero on success; a negated errno value on failure
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_debugpoint_add(int type, FAR void *addr, size_t size,
|
|
debug_callback_t callback, FAR void *arg);
|
|
|
|
/****************************************************************************
|
|
* Name: up_debugpoint_remove
|
|
*
|
|
* Description:
|
|
* Remove a debugpoint.
|
|
*
|
|
* Input Parameters:
|
|
* type - The debugpoint type. optional value:
|
|
* DEBUGPOINT_WATCHPOINT_RO - Read only watchpoint.
|
|
* DEBUGPOINT_WATCHPOINT_WO - Write only watchpoint.
|
|
* DEBUGPOINT_WATCHPOINT_RW - Read and write watchpoint.
|
|
* DEBUGPOINT_BREAKPOINT - Breakpoint.
|
|
* DEBUGPOINT_STEPPOINT - Single step.
|
|
* addr - The address to be debugged.
|
|
* size - The watchpoint size. only for watchpoint.
|
|
*
|
|
* Returned Value:
|
|
* Zero on success; a negated errno value on failure
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_debugpoint_remove(int type, FAR void *addr, size_t size);
|
|
|
|
#endif
|
|
|
|
/****************************************************************************
|
|
* Name: up_alloc_irq_msi
|
|
*
|
|
* Description:
|
|
* Allocate interrupts for MSI/MSI-X vector.
|
|
*
|
|
* Input Parameters:
|
|
* busno - Bus num that PCI device resides
|
|
* devfn - Device and function number
|
|
* irq - allocated vectors array
|
|
* num - number of vectors to allocate
|
|
*
|
|
* Returned Value:
|
|
* >0: success, return number of allocated vectors,
|
|
* <0: A negative value errno
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_alloc_irq_msi(uint8_t busno, uint32_t devfn, FAR int *irq, int num);
|
|
|
|
/****************************************************************************
|
|
* Name: up_release_irq_msi
|
|
*
|
|
* Description:
|
|
* Allocate interrupts for MSI/MSI-X vector.
|
|
*
|
|
* Input Parameters:
|
|
* bus - Bus that PCI device resides
|
|
* irq - vectors array to release
|
|
* num - number of vectors in array
|
|
*
|
|
* Returned Value:
|
|
* None
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_release_irq_msi(FAR int *irq, int num);
|
|
|
|
#ifdef CONFIG_PCI
|
|
|
|
/****************************************************************************
|
|
* Name: up_connect_irq
|
|
*
|
|
* Description:
|
|
* Connect interrupt for MSI/MSI-X.
|
|
*
|
|
* Input Parameters:
|
|
* irq - vectors array
|
|
* num - number of vectors in array
|
|
* mar - returned value for Message Address Register
|
|
* mdr - returned value for Message Data Register
|
|
*
|
|
* Returned Value:
|
|
* >0: success, 0: A positive value errno
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_connect_irq(FAR const int *irq, int num,
|
|
FAR uintptr_t *mar, FAR uint32_t *mdr);
|
|
|
|
/****************************************************************************
|
|
* Name: up_get_legacy_irq
|
|
*
|
|
* Description:
|
|
* Reserve vector for legacy
|
|
*
|
|
****************************************************************************/
|
|
|
|
int up_get_legacy_irq(uint32_t devfn, uint8_t line, uint8_t pin);
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_SYSCALL
|
|
|
|
/****************************************************************************
|
|
* Name: up_assert
|
|
****************************************************************************/
|
|
|
|
void up_assert(FAR const char *filename, int linenum, FAR const char *msg);
|
|
#endif
|
|
|
|
#ifdef CONFIG_ARCH_HAVE_MEMTAG
|
|
|
|
/****************************************************************************
|
|
* Name: up_memtag_bypass
|
|
*
|
|
* Description:
|
|
* Set MTE state bypass or not
|
|
*
|
|
****************************************************************************/
|
|
|
|
bool up_memtag_bypass(bool bypass);
|
|
|
|
/****************************************************************************
|
|
* Name: up_memtag_get_tag
|
|
****************************************************************************/
|
|
|
|
uint8_t up_memtag_get_tag(const void *addr);
|
|
|
|
/****************************************************************************
|
|
* Name: up_memtag_get_random_tag
|
|
*
|
|
* Description:
|
|
* Get a random label based on the address through the mte register
|
|
*
|
|
****************************************************************************/
|
|
|
|
uint8_t up_memtag_get_random_tag(const void *addr);
|
|
|
|
/****************************************************************************
|
|
* Name: up_memtag_set_tag
|
|
*
|
|
* Description:
|
|
* Get the address with label
|
|
*
|
|
****************************************************************************/
|
|
|
|
void *up_memtag_set_tag(const void *addr, uint8_t tag);
|
|
|
|
/****************************************************************************
|
|
* Name: up_memtag_tag_mem
|
|
*
|
|
* Description:
|
|
* Set memory tags for a given memory range
|
|
*
|
|
****************************************************************************/
|
|
|
|
void up_memtag_tag_mem(const void *addr, size_t size);
|
|
|
|
#endif /* CONFIG_ARCH_HAVE_MEMTAG */
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif /* __INCLUDE_NUTTX_ARCH_H */
|