bsp: Add new version xilkernel_v6_2 and deprecate xilkernel_v6_1
This patch add's new version of xilkernel and deprecates the older version of the xilkernel. Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
This commit is contained in:
parent
a1b1070f78
commit
c38b798468
85 changed files with 14836 additions and 0 deletions
172
lib/bsp/xilkernel/data/xilkernel.mld
Executable file
172
lib/bsp/xilkernel/data/xilkernel.mld
Executable file
|
@ -0,0 +1,172 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# $Id: xilkernel_v2_1_0.mld,v 1.1.2.2 2011/12/08 08:17:56 anirudh Exp $
|
||||
###############################################################################
|
||||
|
||||
OPTION psf_version = 2.1.0 ;
|
||||
BEGIN OS xilkernel
|
||||
|
||||
OPTION DRC = kernel_drc ;
|
||||
OPTION SUPPORTED_PERIPHERALS = (microblaze);
|
||||
OPTION COPYFILES = all;
|
||||
OPTION DEPENDS = (standalone);
|
||||
OPTION APP_COMPILER_FLAGS = "-D __XMK__";
|
||||
OPTION APP_LINKER_FLAGS = "-lxilkernel";
|
||||
OPTION OS_STATE = ACTIVE;
|
||||
OPTION VERSION = 6.2;
|
||||
OPTION NAME = xilkernel;
|
||||
|
||||
OPTION DESC = "Xilkernel is a simple and lightweight kernel that provides POSIX style services such as scheduling, threads, synchronization, message passing and timers. The kernel requires a programmable timer that is either built-in or attached to the processor as a peripheral.";
|
||||
|
||||
# STDIN/STDOUT
|
||||
PARAM name = stdin, type = peripheral_instance, requires_interface = stdin, default=none, desc = "Specify the instance name of the standard input peripheral";
|
||||
PARAM name = stdout, type = peripheral_instance, requires_interface = stdout, default=none, desc = "Specify the instance name of the standard output peripheral";
|
||||
|
||||
# System timer specification
|
||||
BEGIN CATEGORY systmr_spec
|
||||
PARAM name = systmr_spec, type = bool, default = true, desc = "Configure kernel timer parameters", permit = none;
|
||||
PARAM name = systmr_dev, type = peripheral_instance, default = none, range = (opb_timer, fit_timer, xps_timer, axi_timer), desc = "Specify the instance name of the kernel timer device (Microblaze only): ";
|
||||
PARAM name = systmr_freq, type = int, default = 100000000, desc = "Specify the clock frequency of the timer (Hz). For PPC it is the PPC405's frequency. For MB systems with an opb_timer, it is the frequency of the clock that drives the timer (OPB bus frequency). With a fit_timer it is the frequency of the fit timer's clock."
|
||||
PARAM name = systmr_interval, type = int, default = 10, desc = "Specify the time interval for each kernel tick (in milliseconds). This controls the CPU budget for each process. If the timer is fit_timer, then this parameter is automatically determined";
|
||||
END CATEGORY
|
||||
|
||||
# System interrupt controller specification
|
||||
PARAM name = sysintc_spec, type = peripheral_instance, range = (opb_intc, xps_intc, dcr_intc, axi_intc), default = none, desc = "Specify the instance name of the interrupt controller device driving system interrupts";
|
||||
|
||||
# pthread feature
|
||||
BEGIN CATEGORY config_pthread_support
|
||||
PARAM name = config_pthread_support, type = bool, default = true, permit = user, desc = "Configure pthread support in the kernel";
|
||||
PARAM name = max_pthreads, type = int, default = 10, desc = "Maximum number of simultaneous threads that can be handled by the kernel";
|
||||
PARAM name = pthread_stack_size, type = int, default = 1000, desc = "Size of the stack to be allocated for each thread";
|
||||
|
||||
BEGIN ARRAY static_pthread_table
|
||||
PROPERTY desc = "Static specification of pthreads. These threads will be created at Xilkernel startup";
|
||||
PARAM name = pthread_start_func, type = string, desc = "Specify the function name at which this pthread will start";
|
||||
PARAM name = pthread_prio, type = int, desc = "Specify the priority of the pthread";
|
||||
END ARRAY
|
||||
|
||||
# pthread_mutex feature
|
||||
PARAM name = config_pthread_mutex, type = bool, default = false, permit = user, desc = "Configure pthread mutex lock support in the kernel";
|
||||
PARAM name = max_pthread_mutex, type = int, default = 10, desc = "Maximum number of mutex locks allocated and supported by the kernel at any point in time";
|
||||
PARAM name = max_pthread_mutex_waitq, type = int, default = 10, type = int, desc = "Length of each mutex lock's wait queue. Controls the maximum the number of processes that can be blocked on this resource";
|
||||
END CATEGORY
|
||||
|
||||
# scheduling features
|
||||
BEGIN CATEGORY config_sched
|
||||
PARAM name = config_sched, desc = "Configure the scheduling scheme used by the kernel", type = bool, default = true, permit = user ;
|
||||
PARAM name = sched_type, type = enum, values = ("Round-Robin" = SCHED_RR, "Priority" = SCHED_PRIO), default = SCHED_RR, desc = "Choose the global kernel scheduling policy";
|
||||
PARAM name = n_prio, type = int, default = 32, dep = (sched_type = SCHED_PRIO), desc = "The number of priority levels if scheduling is priority based";
|
||||
PARAM name = max_readyq, type = int, default = 10, desc = "Length of each ReadyQ. This is the maximum number of processes that can be active at any time";
|
||||
END CATEGORY
|
||||
|
||||
# time features
|
||||
BEGIN CATEGORY config_time
|
||||
PARAM name = config_time, type = bool, default = false, permit = user, desc = "Configure time/timer related feature support in the kernel";
|
||||
PARAM name = max_tmrs, type = int, default = 10, permit = user, desc = "Maximum number of soft timers that will be supported by the kernel at any point in time";
|
||||
END CATEGORY
|
||||
|
||||
# semaphore feature
|
||||
BEGIN CATEGORY config_sema
|
||||
PARAM name = config_sema, type = bool,default = false, permit = user, desc = "Configure semaphore support in the kernel";
|
||||
PARAM name = max_sem, type = int, default = 10, desc = "Maximum number of semaphores allocated and supported by the kernel at any point in time";
|
||||
PARAM name = max_sem_waitq, type = int, default = 10, desc = "Length of each semaphore's wait queue. Controls the maximum the number of processes that can be blocked on this resource";
|
||||
PARAM name = config_named_sema, type = bool, default = false, permit = user, desc = "Configure named semaphore support in the kernel. This is an enhanced semaphore interface defined in POSIX.";
|
||||
END CATEGORY
|
||||
|
||||
# message queue feature - Requires the semaphore feature to be selected
|
||||
BEGIN CATEGORY config_msgq
|
||||
PARAM name = config_msgq, type = bool, default = false, dep = (config_sema = true), permit = user, desc = "Configure message queue support in the kernel";
|
||||
PARAM name = num_msgqs, type = int, default = 10, desc = "Maximum number of message queues allocated and supported by the kernel at any point in time";
|
||||
PARAM name = msgq_capacity, type = int, default = 10, desc = "Message queue capacity - The maximum number of messages that can be stored in the message queue at any point in time";
|
||||
PARAM name = use_malloc, type = bool, default = false, desc = "Use malloc() and free () to allocate space for messages in all queues. If false, Xilkernel's bufmalloc and buffree APIs will be used internally (requires corresponding mem_table parameter to setup block memory allocation for all possible message sizes). Using this will cause message queues to be more powerful (do not require block memory configuration), but slower and bigger at the samef time.";
|
||||
END CATEGORY
|
||||
|
||||
# shared memory feature
|
||||
BEGIN CATEGORY config_shm
|
||||
PARAM name = config_shm, type = bool, default = false, permit = user, desc = "Configure shared memory support in the kernel";
|
||||
BEGIN ARRAY shm_table
|
||||
PROPERTY desc = "Shared Memory Table. List the different shared memory segments. The kernel pre-allocates and supports only these segments";
|
||||
PROPERTY size = n_shm;
|
||||
PARAM name = shm_size, type = int, desc = "Size of shared memory segment";
|
||||
END ARRAY
|
||||
END CATEGORY
|
||||
|
||||
# Buffer malloc feature
|
||||
BEGIN CATEGORY config_bufmalloc
|
||||
PARAM name = config_bufmalloc, type = bool, default = false, permit = user, desc = "Configure buffer memory pool allocation support in the kernel";
|
||||
PARAM name = max_bufs, type = int, default = 10, permit = user, desc = "Maxmimum number of memory pools that can be supported by the kernel at any point in time";
|
||||
BEGIN ARRAY mem_table
|
||||
PROPERTY desc = "Block Memory Table - List statically created memory pool configurations";
|
||||
PROPERTY size = n_malloc_blocks;
|
||||
PARAM name = mem_bsize, type = int, desc = "Memory block size";
|
||||
PARAM name = mem_nblks, type = int, desc = "Maximum number of memory blocks of this size that can be allocated by the kernel";
|
||||
END ARRAY
|
||||
END CATEGORY
|
||||
|
||||
# process management feature
|
||||
BEGIN CATEGORY config_elf_process
|
||||
PARAM name = config_elf_process, type = bool, default = false, permit = user, desc = "Configure ELF process management support in the kernel. This feature is not required to be used, unless you have special requirements to launch processes from separate ELF files. See xilkernel documentation for more info.", state = deprecated;
|
||||
PARAM name = max_procs, type = int, default = 10, desc = "Maximum number of simulataneous ELF processes to be handled by the kernel";
|
||||
# Statically created ELF process parameters.
|
||||
BEGIN ARRAY static_elf_process_table
|
||||
PROPERTY desc = "Static specification of processes that are separate executables. These processes will be created at Xilkernel startup.";
|
||||
PARAM name = process_start_addr, type = int, desc = "Start address of the process";
|
||||
PARAM name = process_prio, type = int, desc = "Priority of the process";
|
||||
END ARRAY
|
||||
END CATEGORY
|
||||
|
||||
# copyout options
|
||||
BEGIN CATEGORY copyoutfiles
|
||||
PARAM name = copyoutfiles, type = bool, default = false, permit = user, desc = "Copy OS files to user specified directory";
|
||||
PARAM name = copytodir, type = string, default = "../copyoflib", desc = "Destination directory for copy";
|
||||
END CATEGORY
|
||||
|
||||
#PARAMETER name = config_stats, type = bool, default = false, permit = user, desc = "Configure support for retrieving kernel statistics";
|
||||
|
||||
BEGIN CATEGORY config_debug_support
|
||||
PARAM name = config_debug_support, type = bool, default = false, desc = "Control various debugging features of the kernel";
|
||||
|
||||
# Disable/Enable debug messages
|
||||
PARAM name = verbose, type = bool, default = false, desc = "Enable debug/diagnostic messages from the kernel on standard output";
|
||||
|
||||
# Disable/Enable debug monitor routines
|
||||
PARAM name = debug_mon, type = bool, default = false, desc = "Enable debug monitor routines in the kernel image";
|
||||
END CATEGORY
|
||||
|
||||
BEGIN CATEGORY enhanced_features
|
||||
PARAM name = enhanced_features, type = bool, default = false, permit = user, desc = "Configure enhanced features of the kernel";
|
||||
PARAM name = config_kill, type = bool, default = false, desc = "Include the kill() function. Enables killing processes dynamically";
|
||||
PARAM name = config_yield, type = bool, default = false, desc = "Include the yield() function. Makes the current process yield to the next process in the queue";
|
||||
END CATEGORY
|
||||
|
||||
END OS
|
11
lib/bsp/xilkernel/data/xilkernel.mss
Executable file
11
lib/bsp/xilkernel/data/xilkernel.mss
Executable file
|
@ -0,0 +1,11 @@
|
|||
|
||||
PARAMETER VERSION = 2.2.0
|
||||
|
||||
BEGIN OS
|
||||
PARAMETER OS_NAME = xilkernel
|
||||
PARAMETER STDIN = *
|
||||
PARAMETER STDOUT = *
|
||||
PARAMETER SYSTMR_SPEC = true
|
||||
PARAMETER SYSTMR_DEV = *
|
||||
PARAMETER SYSINTC_SPEC = *
|
||||
END
|
1037
lib/bsp/xilkernel/data/xilkernel.tcl
Executable file
1037
lib/bsp/xilkernel/data/xilkernel.tcl
Executable file
File diff suppressed because it is too large
Load diff
176
lib/bsp/xilkernel/src/ChangeLog
Executable file
176
lib/bsp/xilkernel/src/ChangeLog
Executable file
|
@ -0,0 +1,176 @@
|
|||
Change Log for Xilkernel
|
||||
=================================
|
||||
2011-08-22
|
||||
version v5_01a
|
||||
* init.h, ksched.h, ksemaphore.h, mem.h, process.h, timer.h, xtrace.h,
|
||||
xmk.h, libprocess.c, libtimer.c, microblaze/debugmon.c, microblaze/mpu.c,
|
||||
microblaze/timer_intr_handler.c, ppc/debugmon.c, ppc/ppc_hw.c, sched.c,
|
||||
ppc/timer_intr_handler.c, bufmalloc.c, intr.c, mem.c, process.c, timer.c:
|
||||
Removed compilation issues that are found when compiled with
|
||||
GCC "-Wstrict-prototype" option. Some of the typical changes made are:
|
||||
"void soft_tmr_init();" is changed to "void soft_tmr_init(void);".
|
||||
|
||||
The main.c at src/sys directory is renamed to xilkernel_main.c to avoid
|
||||
conflicts during debugging.
|
||||
|
||||
include/arch/microblaze/arch.h: Two more regs are added to the process
|
||||
context. These new regs will be used only when stack protection is
|
||||
enabled in microblaze. Otherwise they will be dummies.
|
||||
|
||||
include/sys/decls.h: Externs for _ftext, _etext, _fdata, _edata,
|
||||
_frodata, _erodata, _stack_end, _stack, _fstack_guard_top,
|
||||
_estack_guard_top, _fstack_guard_bottom, and _estack_guard_bottom
|
||||
are added.
|
||||
|
||||
microblaze/entry.S: Code added for saving and restoring the SHR and SLR
|
||||
registers when microblaze stack protection is enabled in the hardware.
|
||||
|
||||
microblaze/hw_exception_handler.S: Code added for the new stack protection
|
||||
exception. It is identical to what is present for standalone BSP.
|
||||
|
||||
microblaze/mpu.c : Vector table is added to the TLB entries, The externs
|
||||
for _ftext, _etext, _fdata, _edata,_frodata, _erodata, _stack_end,
|
||||
_stack, _fstack_guard_top, _estack_guard_top, _fstack_guard_bottom,
|
||||
and _estack_guard_bottom are removed.
|
||||
|
||||
microblaze/mb-hw.c: In function "setup_initial_context", code added to
|
||||
store the stack limits. In function init_idle_task, code added to store
|
||||
the stack limits and initialize the SHR and SLR regs. Also MACROs for
|
||||
writing to/reading from SHR/SLR regs are added. Changes done in function
|
||||
"microblaze_report_exception" to remove warnings. Lines of code added to
|
||||
zero out "esr", "ear" and "pc" after they are used. Changes done at
|
||||
many places in the file to remove warnings found with GCC
|
||||
"-Wstrict-prototype" option. In function "microblaze_report_exception",
|
||||
the existing "DPRINTF"s are replaced with xil_printfs.
|
||||
|
||||
sys/pthread.c: Code added to pass the stacksize while calling
|
||||
"setup_initial_context". The stacksize passed is used for microblaze and in
|
||||
general can be handy for future enhancements.
|
||||
|
||||
sys/elf.c: Extra "stacksize" argument added for the "setup_initial_context"
|
||||
call.
|
||||
|
||||
ppc/ppc-hw.c: Extra "stacksize" argument added for the "setup_initial_context"
|
||||
call. It is zeroed out to remove compilation warnings.
|
||||
|
||||
ppc/timer_intr_handler.c: In function "timer_int_handler" the passed argument
|
||||
is zeroed out to remove compilation warning.
|
||||
|
||||
xilkernel_v2_1_0.tcl: Changes done so that function prototypes generated for
|
||||
static thread entry functions do not lead to warnings during compilation
|
||||
(with GCC "-Wstrict-prototype" option).
|
||||
|
||||
|
||||
|
||||
2010-09-14
|
||||
* src/src/arch/microblaze/hw_exception_handler.S: Added in xparameters.h
|
||||
so that exception enable information is available.
|
||||
|
||||
2010-04-20
|
||||
* src/src/sys/timer.c: Make timer calculations avoid overflow.
|
||||
|
||||
2010-02-08
|
||||
* src/src/arch/microblaze/mb-hw.c, src/src/arch/ppc/ppc-hw.c,
|
||||
src/src/sys/main.c, src/include/sys/arch.h: Adapted to work with
|
||||
new HAL API from standalone_v3.
|
||||
|
||||
2010-02-08
|
||||
* data/xilkernel_v2_1_0.tcl: Add DRC for pthread stack size.
|
||||
|
||||
2010-01-27
|
||||
* src/include/sys/init.h, src/src/sys/main.c: Protos for
|
||||
xilkernel_init and xilkernel_start.
|
||||
|
||||
2009-12-17
|
||||
* data/xilkernel_v2_1_0.mld, data/xilkernel_v2_1_0.tcl: New
|
||||
standalone version. Change dependency to standalone_v3_00_a. Do
|
||||
the necessary management of standalone_v3 sources.
|
||||
|
||||
2008-11-17
|
||||
|
||||
* src/src/sys/main.c, src/include/sys/init.h: Add new API
|
||||
xmk_add_static_thread(). This function can be used prior to
|
||||
xilkernel_init() to add startup threads via application code.
|
||||
|
||||
2008-11-06
|
||||
|
||||
* data/xilkernel.tcl: Modify TCL iteration of I/O ranges to
|
||||
accomodate changes in the the hardware TCL interface.
|
||||
|
||||
2008-10-28
|
||||
|
||||
* src/include/sys/bufmalloc.h src/include/sys/init.h
|
||||
src/include/sys/kpthread.h src/include/sys/ksched.h
|
||||
src/include/sys/ksemaphore.h src/include/sys/mem.h
|
||||
src/include/sys/process.h src/Makefile_ppc.sh
|
||||
src/src/arch/microblaze/mb-hw.c src/src/arch/ppc/ppc-hw.c
|
||||
src/src/ipc/msg.c src/src/ipc/semaphore.c src/src/ipc/shm.c
|
||||
src/src/sys/bufmalloc.c src/src/sys/main.c src/src/sys/process.c
|
||||
src/src/sys/pthread.c src/src/sys/sched.c src/src/sys/timer.c :
|
||||
Fix warnings exposed by -Wall.
|
||||
|
||||
2008-02-20
|
||||
|
||||
* src/src/sys/alloc.c: Make kernel stack size equal to the greater
|
||||
of 1024 bytes or pthread_stack_size. New stack start pointer
|
||||
variable used to switch stacks in kernel entry routines.
|
||||
* src/include/arch/<processor>/arch.h: Remove KERNEL_IRQ_STACKSZ
|
||||
* src/src/arch/<processor>/entry<sub_type>.S: Load new stack
|
||||
pointer from kernel_irq_stack_ptr rather than offset from label
|
||||
kernel_irq_stack.
|
||||
|
||||
2007-10-22
|
||||
|
||||
* data/xilkernel_v2_1_0.mld: Change depends tag to standalone_v2_00_a.
|
||||
|
||||
2007-10-15
|
||||
|
||||
* Makefile_mb.sh: Fix regression with compiler used in kernel Make. Always
|
||||
use *-gcc
|
||||
|
||||
* timer.h: Add prototype for xget_clock_ticks
|
||||
|
||||
2007-09-26
|
||||
|
||||
* ktypes.h: Add new field 'remain' for storing process timeout information
|
||||
|
||||
* process.c: When unblocking a process waiting on a timeout, store the
|
||||
remaining timeout amount in the process data structure.
|
||||
|
||||
* semaphore.c: Add sys/timer.h to includes
|
||||
|
||||
* timer.c: Cleanup prototypes. Add new function to compute ticks_to_ms.
|
||||
Store timeout remaining in process data structure. Update to remove_tmr
|
||||
on 2007-09-11 was not sufficient. Since the previous scheme required an
|
||||
interrupt to deallocate removed timers. It could cause an application to
|
||||
run out of timers, before the next interrupt. Created new scheme, where
|
||||
active_tmr lists are updated promptly upon a timer being deactivated.
|
||||
|
||||
* xtrace.c/.h: New xtrace API for internal use. Minimally intrusive way
|
||||
to instrument kernel and log events of interest. Log gets printed out
|
||||
later through debugger. Not available through MSS.
|
||||
|
||||
2007-09-19
|
||||
|
||||
* timer_intr_handler.c/<arch>-hw.c: Fix for bug where threads could starve
|
||||
because of the way we always used to refresh PIT timer. Now, when a thread
|
||||
receives only a partial tick, the timer is not refreshed and instead the
|
||||
thread receives one more full time quantum. cr=448047
|
||||
|
||||
2007-09-11
|
||||
|
||||
* timer.c: Fix bug with timer handling of closely scheduled add/remove
|
||||
of timers. The changes make sure that no ghost timers are left in the
|
||||
timer lists and there are no aliasing effects. cr=448047
|
||||
|
||||
2014-04-15
|
||||
|
||||
* modified driver tcl to remove _interrupt_handler.o from libgloss.a
|
||||
instead of libxil.a
|
||||
|
||||
2014-04-29
|
||||
|
||||
* modified driver tcl to use libxil.a if libgloss.a does not exist
|
||||
|
||||
2014-06-27
|
||||
* Fixed the CR:802962 and the CR:803104 changes are made in the tcl file
|
161
lib/bsp/xilkernel/src/Makefile_mb.sh
Executable file
161
lib/bsp/xilkernel/src/Makefile_mb.sh
Executable file
|
@ -0,0 +1,161 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Top level Makefile
|
||||
#
|
||||
# $Id: Makefile_mb.sh,v 1.1.2.1 2011/08/25 12:12:50 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#
|
||||
# Processor architecture
|
||||
# microblaze
|
||||
#
|
||||
ARCH = microblaze
|
||||
|
||||
SYSTEMDIR = ../../..
|
||||
|
||||
TOPDIR = .
|
||||
|
||||
ARCH_PREFIX = mb
|
||||
|
||||
#
|
||||
# gnu tools for Makefile
|
||||
#
|
||||
CC = $(ARCH_PREFIX)-gcc
|
||||
AR = $(ARCH_PREFIX)-ar
|
||||
CP = cp
|
||||
|
||||
# export ARCH ARCH_PREFIX ARCH_DEFINE CC AR CP
|
||||
|
||||
#
|
||||
# Compiler, linker and other options.
|
||||
#
|
||||
CFLAGS = ${COMPILER_FLAGS} -D__XMK__ ${EXTRA_COMPILER_FLAGS}
|
||||
|
||||
#
|
||||
# System project directories.
|
||||
#
|
||||
|
||||
LIBDIR = $(SYSTEMDIR)/lib
|
||||
INCLUDEDIR = $(SYSTEMDIR)/include
|
||||
|
||||
# ELF process's system call wrapper library
|
||||
LIBSYSCALL = ${TOPDIR}/libsyscall.a
|
||||
|
||||
# Kernel library. Contains system call wrappers and the entire kernel
|
||||
LIBXILKERNEL = ${LIBDIR}/libxil.a
|
||||
LIBXILKERNEL_OLD = ${TOPDIR}/libxilkernel.a
|
||||
|
||||
INCLUDES = -I${TOPDIR}/include -I$(INCLUDEDIR)
|
||||
LIBS = -L${TOPDIR} -L$(LIBDIR)
|
||||
|
||||
# These objects go into libxil.a for linking with kernel bundled threads
|
||||
KERNEL_AR_OBJS = ${TOPDIR}/src/sys/*.o ${TOPDIR}/src/ipc/*.o ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o ${TOPDIR}/src/arch/${ARCH}/debugmon.o
|
||||
KERNEL_AR_OBJS_2 = ${TOPDIR}/src/arch/${ARCH}/*.o
|
||||
|
||||
# These objects go into the ELF process system call wrapper library - libsyscall.a
|
||||
LIBSYSCALL_OBJS = ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o
|
||||
|
||||
INCLUDEFILES = ${TOPDIR}/include/*
|
||||
|
||||
STANDALONE_STDIN_SRC = inbyte.c
|
||||
STANDALONE_STDOUT_SRC = outbyte.c
|
||||
STANDALONE_STDIN_OBJ = inbyte.o
|
||||
STANDALONE_STDOUT_OBJ = outbyte.o
|
||||
|
||||
LIBXIL = libxil.a
|
||||
|
||||
#SUBDIRS = dir_src
|
||||
SUBDIRS =
|
||||
|
||||
libs: real_libs
|
||||
echo "Compiling xilkernel"
|
||||
$(MAKE) -f Makefile_depends -e "COMPILER_FLAGS=$(COMPILER_FLAGS)" "EXTRA_COMPILER_FLAGS=$(EXTRA_COMPILER_FLAGS)" -C ../../standalone/src libs
|
||||
|
||||
echo "killing the .o files"
|
||||
$(ARCHIVER) -d ${LIBXIL} errno.o
|
||||
$(ARCHIVER) -d ${LIBXIL} kill.o
|
||||
real_libs: dir_syscall dir_src standalone rellibs
|
||||
|
||||
|
||||
|
||||
|
||||
dir_src:
|
||||
$(MAKE) -C src CFLAGS="$(CFLAGS)" ARCH="$(ARCH)" CC="$(CC)" AR="$(AR)" all
|
||||
|
||||
dir_syscall:
|
||||
$(MAKE) -C syscall CFLAGS="$(CFLAGS)" ARCH="$(ARCH)" CC="$(CC)" AR="$(AR)" libs
|
||||
|
||||
|
||||
#
|
||||
# This target is required because of the way inbyte.c and outbyte.c get
|
||||
# generated under xilkernel instead of standalone. This is due to the behavior
|
||||
# of standard tcl library routines xhandle_stdin and xhandle_stdout
|
||||
#
|
||||
|
||||
standalone:
|
||||
$(CC) $(CFLAGS) -c $(INCLUDES) $(STANDALONE_STDIN_SRC)
|
||||
$(AR) -r $(LIBDIR)/$(LIBXIL) $(STANDALONE_STDIN_OBJ)
|
||||
$(CC) $(CFLAGS) -c $(INCLUDES) $(STANDALONE_STDOUT_SRC)
|
||||
$(AR) -r $(LIBDIR)/$(LIBXIL) $(STANDALONE_STDOUT_OBJ)
|
||||
|
||||
# Does not work on SOL !!
|
||||
#.PHONY: include
|
||||
|
||||
include: standalone_include dummy
|
||||
$(CP) -rf $(INCLUDEFILES) $(INCLUDEDIR)
|
||||
|
||||
standalone_include:
|
||||
$(MAKE) -f Makefile_depends -e "COMPILER_FLAGS=$(COMPILER_FLAGS)" "EXTRA_COMPILER_FLAGS=$(EXTRA_COMPILER_FLAGS)" -C ../../standalone/src include
|
||||
|
||||
dummy:
|
||||
|
||||
rellibs: standalone
|
||||
|
||||
$(AR) -r ${LIBSYSCALL} $(LIBSYSCALL_OBJS)
|
||||
$(CP) $(LIBSYSCALL) $(LIBDIR)
|
||||
$(AR) -r ${LIBXILKERNEL} $(KERNEL_AR_OBJS)
|
||||
$(AR) -r ${LIBXILKERNEL_OLD} ${KERNEL_AR_OBJS_2}
|
||||
$(CP) $(LIBXILKERNEL_OLD) $(LIBDIR)
|
||||
|
||||
clean:
|
||||
$(MAKE) -C src ARCH="$(ARCH)" clean
|
||||
$(MAKE) -C syscall ARCH="$(ARCH)" clean
|
||||
rm -f ${LIBSYSCALL}
|
146
lib/bsp/xilkernel/src/Makefile_ppc.sh
Executable file
146
lib/bsp/xilkernel/src/Makefile_ppc.sh
Executable file
|
@ -0,0 +1,146 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Top level Makefile
|
||||
#
|
||||
# $Id: Makefile_mb.sh,v 1.1.2.1 2011/08/25 12:12:50 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#
|
||||
# Processor architecture
|
||||
# microblaze
|
||||
#
|
||||
ARCH = microblaze
|
||||
|
||||
SYSTEMDIR = ../../..
|
||||
|
||||
TOPDIR = .
|
||||
|
||||
ARCH_PREFIX = mb
|
||||
|
||||
#
|
||||
# gnu tools for Makefile
|
||||
#
|
||||
CC = $(ARCH_PREFIX)-gcc
|
||||
AR = $(ARCH_PREFIX)-ar
|
||||
CP = cp
|
||||
|
||||
# export ARCH ARCH_PREFIX ARCH_DEFINE CC AR CP
|
||||
|
||||
#
|
||||
# Compiler, linker and other options.
|
||||
#
|
||||
CFLAGS = ${COMPILER_FLAGS} -D__XMK__ ${EXTRA_COMPILER_FLAGS}
|
||||
|
||||
#
|
||||
# System project directories.
|
||||
#
|
||||
|
||||
LIBDIR = $(SYSTEMDIR)/lib
|
||||
INCLUDEDIR = $(SYSTEMDIR)/include
|
||||
|
||||
# ELF process's system call wrapper library
|
||||
LIBSYSCALL = ${TOPDIR}/libsyscall.a
|
||||
|
||||
# Kernel library. Contains system call wrappers and the entire kernel
|
||||
LIBXILKERNEL = ${LIBDIR}/libxil.a
|
||||
LIBXILKERNEL_OLD = ${TOPDIR}/libxilkernel.a
|
||||
|
||||
INCLUDES = -I${TOPDIR}/include -I$(INCLUDEDIR)
|
||||
LIBS = -L${TOPDIR} -L$(LIBDIR)
|
||||
|
||||
# These objects go into libxil.a for linking with kernel bundled threads
|
||||
KERNEL_AR_OBJS = ${TOPDIR}/src/sys/*.o ${TOPDIR}/src/ipc/*.o ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o ${TOPDIR}/src/arch/${ARCH}/debugmon.o
|
||||
KERNEL_AR_OBJS_2 = ${TOPDIR}/src/arch/${ARCH}/*.o
|
||||
|
||||
# These objects go into the ELF process system call wrapper library - libsyscall.a
|
||||
LIBSYSCALL_OBJS = ${TOPDIR}/syscall/arch/${ARCH}/*.o ${TOPDIR}/syscall/*.o
|
||||
|
||||
INCLUDEFILES = ${TOPDIR}/include/*
|
||||
|
||||
STANDALONE_STDIN_SRC = inbyte.c
|
||||
STANDALONE_STDOUT_SRC = outbyte.c
|
||||
STANDALONE_STDIN_OBJ = inbyte.o
|
||||
STANDALONE_STDOUT_OBJ = outbyte.o
|
||||
|
||||
LIBXIL = libxil.a
|
||||
|
||||
#SUBDIRS = dir_src
|
||||
SUBDIRS =
|
||||
|
||||
libs: real_libs
|
||||
echo "Compiling xilkernel"
|
||||
|
||||
real_libs: dir_syscall dir_src standalone rellibs
|
||||
|
||||
dir_src:
|
||||
$(MAKE) -C src CFLAGS="$(CFLAGS)" ARCH="$(ARCH)" CC="$(CC)" AR="$(AR)" all
|
||||
|
||||
dir_syscall:
|
||||
$(MAKE) -C syscall CFLAGS="$(CFLAGS)" ARCH="$(ARCH)" CC="$(CC)" AR="$(AR)" libs
|
||||
|
||||
|
||||
#
|
||||
# This target is required because of the way inbyte.c and outbyte.c get
|
||||
# generated under xilkernel instead of standalone. This is due to the behavior
|
||||
# of standard tcl library routines xhandle_stdin and xhandle_stdout
|
||||
#
|
||||
|
||||
standalone:
|
||||
|
||||
# Does not work on SOL !!
|
||||
#.PHONY: include
|
||||
|
||||
include: dummy
|
||||
$(CP) -rf $(INCLUDEFILES) $(INCLUDEDIR)
|
||||
|
||||
dummy:
|
||||
|
||||
rellibs: standalone
|
||||
$(AR) -r ${LIBSYSCALL} $(LIBSYSCALL_OBJS)
|
||||
$(CP) $(LIBSYSCALL) $(LIBDIR)
|
||||
$(AR) -r ${LIBXILKERNEL} $(KERNEL_AR_OBJS)
|
||||
$(AR) -r ${LIBXILKERNEL_OLD} ${KERNEL_AR_OBJS_2}
|
||||
$(CP) $(LIBXILKERNEL_OLD) $(LIBDIR)
|
||||
|
||||
clean:
|
||||
$(MAKE) -C src ARCH="$(ARCH)" clean
|
||||
$(MAKE) -C syscall ARCH="$(ARCH)" clean
|
||||
rm -f ${LIBSYSCALL}
|
72
lib/bsp/xilkernel/src/include/arch/microblaze/arch.h
Executable file
72
lib/bsp/xilkernel/src/include/arch/microblaze/arch.h
Executable file
|
@ -0,0 +1,72 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file arch.h
|
||||
//! Microblaze specific definitions, constants, declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _MB_ARCH_H
|
||||
#define _MB_ARCH_H
|
||||
|
||||
#define STACK_ALIGN 4
|
||||
|
||||
#ifndef __ASM__
|
||||
|
||||
#define SSTACK_PTR_ADJUST ((int)0)
|
||||
//! Process Management Data Structures
|
||||
//! Context data structure
|
||||
struct _process_context {
|
||||
unsigned int regs[35];
|
||||
char isrflag;
|
||||
|
||||
} __attribute__ ((packed, aligned(STACK_ALIGN)));
|
||||
|
||||
#define PCONTEXT_SIZ (sizeof(struct _process_context))
|
||||
|
||||
#else
|
||||
|
||||
#define SSTACK_PTR_ADJUST (0)
|
||||
|
||||
#endif /* __ASM__ */
|
||||
|
||||
// Various offsets within the context structure
|
||||
#define CTX_OFFSET (0) // Offset of context structure within process structure
|
||||
#define CTX_REG_OFFSET(regnum) (CTX_OFFSET + 4*(regnum)) // Offset of a register in the context save structure
|
||||
#define CTX_SIZE (35 * 4)
|
||||
#define ISRFLAG_OFFSET (CTX_OFFSET + CTX_SIZE)
|
||||
#define ISRFLAG_SYSTEM_CALL 0
|
||||
#define ISRFLAG_INTERRUPT 1
|
||||
#define ISRFLAG_NEW_PROC 2
|
||||
|
||||
|
||||
#define PROCESS_STARTUP_STACKSZ 400
|
||||
|
||||
#endif /* _MB_ARCH_H */
|
114
lib/bsp/xilkernel/src/include/arch/ppc/arch.h
Executable file
114
lib/bsp/xilkernel/src/include/arch/ppc/arch.h
Executable file
|
@ -0,0 +1,114 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file arch.h
|
||||
//! PPC405 specific definitions, constants, declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _PPC_ARCH_H
|
||||
#define _PPC_ARCH_H
|
||||
|
||||
#define STACK_ALIGN 8
|
||||
|
||||
#ifndef __ASM__
|
||||
#define SSTACK_PTR_ADJUST ((int)-8)
|
||||
|
||||
//! Process Management Data Structures
|
||||
//! Context data structure
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Context map:
|
||||
//
|
||||
// +------------+ + 0
|
||||
// | MSR |
|
||||
// +------------+ + 4
|
||||
// | PC |
|
||||
// +------------+ + 8
|
||||
// | LR |
|
||||
// +------------+ + 12
|
||||
// | CTR |
|
||||
// +------------+ + 16
|
||||
// | XER |
|
||||
// +------------+ + 20
|
||||
// | CR |
|
||||
// +------------+ + 24
|
||||
// | r0 |
|
||||
// | . |
|
||||
// | . |
|
||||
// | . |
|
||||
// | r31 |
|
||||
// +------------+ + 152
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
struct _process_context {
|
||||
unsigned int regs[38]; // Process context information store
|
||||
char isrflag;
|
||||
} __attribute__ ((packed, aligned(STACK_ALIGN)));
|
||||
|
||||
#define PCONTEXT_SIZ (sizeof(struct _process_context))
|
||||
|
||||
#else
|
||||
|
||||
#define SSTACK_PTR_ADJUST (-8)
|
||||
|
||||
#endif
|
||||
|
||||
#define CTX_INDEX_MSR 0
|
||||
#define CTX_INDEX_PC 1
|
||||
#define CTX_INDEX_LR 2
|
||||
#define CTX_INDEX_CTR 3
|
||||
#define CTX_INDEX_XER 4
|
||||
#define CTX_INDEX_CR 5
|
||||
#define CTX_INDEX_GPR(r) (6 + r)
|
||||
|
||||
// Various offsets within the context structure
|
||||
#define CTX_OFFSET (0) // Offset of context structure within process structure
|
||||
#define CTX_MSR_FIELD (0)
|
||||
#define CTX_PC_FIELD (CTX_MSR_FIELD + 4)
|
||||
#define CTX_LR_FIELD (CTX_PC_FIELD + 4)
|
||||
#define CTX_CTR_FIELD (CTX_LR_FIELD + 4)
|
||||
#define CTX_XER_FIELD (CTX_CTR_FIELD + 4)
|
||||
#define CTX_CR_FIELD (CTX_XER_FIELD + 4)
|
||||
#define CTX_GPR_FIELD (CTX_CR_FIELD + 4)
|
||||
#define CTX_GPR_REG_FIELD(reg) (CTX_GPR_FIELD + (reg * 4))
|
||||
#define CTX_SIZE (38 * 4)
|
||||
#define ISRFLAG_OFFSET (CTX_OFFSET + CTX_SIZE)
|
||||
|
||||
#define ISRFLAG_SYSTEM_CALL 0
|
||||
#define ISRFLAG_NON_CRITICAL 1
|
||||
#define ISRFLAG_CRITICAL 2
|
||||
#define ISRFLAG_NEW_PROC 3
|
||||
|
||||
// Various stack sizes used in the kernel
|
||||
#define PROCESS_STARTUP_STACKSZ 400
|
||||
|
||||
#endif /* _PPC_ARCH_H */
|
118
lib/bsp/xilkernel/src/include/config/config_cparam.h
Executable file
118
lib/bsp/xilkernel/src/include/config/config_cparam.h
Executable file
|
@ -0,0 +1,118 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file config_cparam.h
|
||||
//! This contains the configuration parameter's for Message Queue,
|
||||
//! Shared Memory and Dynamic Buffer mgmt routines. The following fields are
|
||||
//! defined based on the values in sys/init.c
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef CONFIG_CPARAM_H
|
||||
#define CONFIG_CPARAM_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory sizes for the various memory blocks */
|
||||
/************************************************************************/
|
||||
|
||||
// The total Memory needed for all PID queue's in the system. This includes
|
||||
// ready queue and semaphore wait queues.
|
||||
|
||||
#ifdef CONFIG_SEMA
|
||||
#define PID_QUEUE_MSIZE ((N_PRIO*MAX_READYQ)+(MAX_SEM*MAX_SEM_WAITQ))
|
||||
#else
|
||||
#define PID_QUEUE_MSIZE (N_PRIO*MAX_READYQ)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
#define PTHREAD_MUTEX_QUEUE_MSIZE (MAX_PTHREAD_MUTEX * MAX_PTHREAD_MUTEX_WAITQ)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
// The total memory needed for all the thread context. Calculated based on
|
||||
// definition in config_param.h
|
||||
#define PTHREAD_STACK_MSIZE (MAX_PTHREADS * PTHREAD_STACK_SIZE)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
// Total Memory size for the various Shared Memory
|
||||
// This is how it is calculated from (struct _shm_init):
|
||||
// -# Add msize of all the shared memory to get the total msize
|
||||
#ifndef SHM_MSIZE
|
||||
#define SHM_MSIZE 100
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MALLOC
|
||||
// Total Memory size for the Dynamic buffer management
|
||||
// This is how it is calculated from (struct _malloc_init):
|
||||
// -# msize for a single memory block = mem_bsize * n_blocks
|
||||
// -# Add msize of all the Memory blocks to get the total msize
|
||||
|
||||
#ifndef MALLOC_MSIZE
|
||||
#define MALLOC_MSIZE 120
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Maximum number of various elements - See config_init.h */
|
||||
/************************************************************************/
|
||||
#ifndef N_INIT_PROCESS
|
||||
#define N_INIT_PROCESS 0
|
||||
#endif
|
||||
|
||||
#ifndef N_INIT_SELF_PTHREADS
|
||||
#define N_INIT_SELF_PTHREADS 0
|
||||
#endif
|
||||
#ifndef N_INIT_MELF_PTHREADS
|
||||
#define N_INIT_MELF_PTHREADS 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
#ifndef N_SHM
|
||||
#define N_SHM 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MALLOC
|
||||
#ifndef N_MALLOC_BLOCKS
|
||||
#define N_MALLOC_BLOCKS 2
|
||||
#endif
|
||||
#ifndef TOT_MALLOC_BLOCKS
|
||||
#define TOT_MALLOC_BLOCKS 20 // Total number of memory blocks in the
|
||||
// system. This is:
|
||||
// - Sum of n_blocks field of all elements in malloc_config[]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
72
lib/bsp/xilkernel/src/include/config/config_init.h
Executable file
72
lib/bsp/xilkernel/src/include/config/config_init.h
Executable file
|
@ -0,0 +1,72 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file config_init.h
|
||||
//! This contains the values for system definition. This can be generated by
|
||||
//! libgen and can also be modified by the user for customization.
|
||||
//! - The structures are declared in sys/init.h
|
||||
//! - If any changes are made to this file by the user, then they also need
|
||||
//! to change the corresponding fields in config_cparam.h file.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <sys/init.h>
|
||||
#include <os_config.h>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! se_process_table contains the information about separate executable processes that
|
||||
//! need to be created during system init. This information is used by se_process_init().
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
struct _process_init se_process_table[] = {
|
||||
{0x0, 0 }
|
||||
} ;
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! shm_config - User defined information about Shared Mem's are defined
|
||||
//! here. It contains information about each shard mem in the system. This
|
||||
//! is used by shm_init().
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
struct _shm_init shm_config[] = {
|
||||
{ 100 },
|
||||
} ;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MALLOC
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! malloc_config - User defined information about dynamic memory blocks are
|
||||
//! defined here. This is used by malloc_init() to initialize the structures.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
const struct _malloc_init malloc_config[] = {
|
||||
{ 4, 10 },
|
||||
{ 8, 10 },
|
||||
} ;
|
||||
#endif
|
131
lib/bsp/xilkernel/src/include/config/config_param.h
Executable file
131
lib/bsp/xilkernel/src/include/config/config_param.h
Executable file
|
@ -0,0 +1,131 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file config_param.h
|
||||
//! This file contains configuration parameter's for process Management,
|
||||
//! thread Management and semaphore routines.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _CONFIG_PARAM_H
|
||||
#define _CONFIG_PARAM_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/ksched.h>
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
#ifdef N_PRIO
|
||||
#undef N_PRIO
|
||||
#endif
|
||||
#define N_PRIO 1 // N_PRIO always 1 for SCHED_RR
|
||||
#define PRIO_HIGHEST 0 // Highest priority
|
||||
#define PRIO_LOWEST 0 // Lowest priority
|
||||
#endif /* SCHED_TYPE == SCHED_RR */
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO // SCHED_PRIO
|
||||
#ifndef N_PRIO // was not defined in os_config.h
|
||||
#define N_PRIO 32 // Number of priority levels
|
||||
#define PRIO_HIGHEST 0 // Highest priority
|
||||
#define PRIO_LOWEST 31 // Least Priority
|
||||
#else
|
||||
#define PRIO_HIGHEST 0
|
||||
#define PRIO_LOWEST (N_PRIO-1)
|
||||
#endif
|
||||
#endif /* SCHED_TYPE == SCHED_PRIO */
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* InterProcess Communication options */
|
||||
/************************************************************************/
|
||||
|
||||
// Semaphore Specific Configs
|
||||
#ifdef CONFIG_SEMA
|
||||
|
||||
#ifndef MAX_SEM
|
||||
#define MAX_SEM 20 // Max Semaphore count
|
||||
#endif
|
||||
#ifndef MAX_SEM_WAITQ
|
||||
#define MAX_SEM_WAITQ 10 // Max semaphore wait Q length
|
||||
#endif
|
||||
#endif /* CONFIG_SEMA */
|
||||
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
#ifndef CONFIG_SEMA
|
||||
#error "Message queues require semaphores. Please define CONFIG_SEMA"
|
||||
#endif
|
||||
#ifndef NUM_MSGQS
|
||||
#define NUM_MSGQS 10
|
||||
#endif
|
||||
#ifndef MSGQ_CAPACITY
|
||||
#define MSGQ_CAPACITY 10
|
||||
#endif
|
||||
#endif /* CONFIG_MSGQ */
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
#ifndef CONFIG_PTHREAD_SUPPORT
|
||||
#error "Pthread mutex requires pthread support. Please define CONFIG_PTHREAD_SUPPORT"
|
||||
#endif
|
||||
#ifndef MAX_PTHREAD_MUTEX
|
||||
#define MAX_PTHREAD_MUTEX 5
|
||||
#endif
|
||||
|
||||
#ifndef MAX_PTHREAD_MUTEX_WAITQ
|
||||
#define MAX_PTHREAD_MUTEX_WAITQ 10 // Max pthread_mutex wait Q length
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
/* Memory Management related options. */
|
||||
/************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
#ifndef MAX_PTHREADS
|
||||
#define MAX_PTHREADS 5 // Max number of threads
|
||||
#endif
|
||||
|
||||
#ifndef PTHREAD_STACK_SIZE
|
||||
#define PTHREAD_STACK_SIZE 600 // Should be a multiple of 4
|
||||
// for word alignment
|
||||
#endif
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
||||
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
#define MAX_PROCESS_CONTEXTS (MAX_PROCS + MAX_PTHREADS)
|
||||
#else
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
#define MAX_PROCESS_CONTEXTS (MAX_PTHREADS)
|
||||
#else
|
||||
#define MAX_PROCESS_CONTEXTS 0
|
||||
#endif
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
||||
|
||||
#endif /* _CONFIG_PARAM_H */
|
131
lib/bsp/xilkernel/src/include/os_config.h
Executable file
131
lib/bsp/xilkernel/src/include/os_config.h
Executable file
|
@ -0,0 +1,131 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file os_config.h
|
||||
//! This file caontains all the configuration #define's for the system. The
|
||||
//! different modules of the kernel can be configured by changing this file
|
||||
//! and recompiling the kernel. Some of the modules that are configurable are:
|
||||
//! - Process Management
|
||||
//! - Thread Management
|
||||
//! - Scheduling type
|
||||
//! - Semaphore
|
||||
//! - Message Queue
|
||||
//! - Shared Memory
|
||||
//! - Dynamic Buffer Management
|
||||
//!
|
||||
//! By recompiling, the kernel gets compiled with the defaults for each
|
||||
//! modules. To further configure the kernel changes may have to be made in the
|
||||
//! following files:
|
||||
//! - config_param.h
|
||||
//! - config_cparam.h
|
||||
//! - config_init.h
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _OS_CONFIG_H
|
||||
#define _OS_CONFIG_H
|
||||
|
||||
//! Timer ticks value used for scheduling.
|
||||
#define TIMER_TICKS 2
|
||||
|
||||
//! Process Management.
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_param.h. The initial system processes are specified in sys/init.c file.
|
||||
#define MAX_PROCS 10 // Max. number of Processesing contexts in the system
|
||||
|
||||
//! Max. number of Processes in each Priority ready queue. This determines the size
|
||||
//! of the Ready Queue. This is determined by the type of application.
|
||||
#define MAX_READYQ 10
|
||||
|
||||
#define CONFIG_KILL 1 //! Include kill() function
|
||||
#define CONFIG_YIELD 1 //! Include yield() function
|
||||
|
||||
//! Type of process scheduling. There two types of scheduling supported and
|
||||
//! can be configured during system build.
|
||||
#define SCHED_TYPE 3 //! SCHED_PRIO
|
||||
|
||||
|
||||
//! ELF Process Management
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_param.h.
|
||||
#define CONFIG_ELF_PROCESS 1 // Support ELF process functionality
|
||||
|
||||
//! Thread Management
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_param.h.
|
||||
#define CONFIG_PTHREAD_SUPPORT 1 //! Support thread functionality
|
||||
|
||||
//! Semaphore
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_param.h.
|
||||
|
||||
//! Include the Semapore module
|
||||
#define CONFIG_SEMA 1
|
||||
|
||||
//! pthread mutex
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_param.h.
|
||||
|
||||
//! Include the Mutex module
|
||||
#define CONFIG_PTHREAD_MUTEX 1
|
||||
|
||||
//! Message Queue
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_cparam.h and sys/init.c.
|
||||
|
||||
//! Include the Message Queue functionality.
|
||||
#define CONFIG_MSGQ 1
|
||||
|
||||
//! Shared Memory
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_cparam.h and sys/init.c.
|
||||
//! Include the Shared Memory Functionality
|
||||
#define CONFIG_SHM 1
|
||||
|
||||
//! Dynamic Buffer Management
|
||||
//! Further configuration of this module can be done by modifying
|
||||
//! config_cparam.h and sys/init.c.
|
||||
//! Include the Dynamic buffer management functionality.
|
||||
#define CONFIG_MALLOC 1
|
||||
|
||||
//! Cache Enable
|
||||
//! For PPC only
|
||||
//! Further configuration can be done by modifying sys/main.c
|
||||
//! Enable caches
|
||||
#define CONFIG_CACHE 1
|
||||
|
||||
//! Configure timer functionality
|
||||
#define CONFIG_TIMERS 1
|
||||
|
||||
//! Vector base address
|
||||
#define CONFIG_BASE_VECTORS 0x00000000
|
||||
|
||||
#endif /* _OS_CONFIG_H */
|
76
lib/bsp/xilkernel/src/include/semaphore.h
Executable file
76
lib/bsp/xilkernel/src/include/semaphore.h
Executable file
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file semaphore.h
|
||||
//! XSI semaphore definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _SEMAPHORE_H
|
||||
#define _SEMAPHORE_H
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <os_config.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SEM_NAME_MAX 25 // Length of symbolic name that can be associated with a semaphore
|
||||
|
||||
#define SEM_FAILED -1 // Error indication
|
||||
|
||||
#ifndef SEM_NSEMS_MAX
|
||||
#define SEM_NSEMS_MAX 10
|
||||
#endif
|
||||
|
||||
#ifndef SEM_VALUE_MAX
|
||||
#define SEM_VALUE_MAX 200
|
||||
#endif
|
||||
|
||||
typedef unsigned int sem_t;
|
||||
|
||||
int sem_init(sem_t* sem, int pshared, unsigned value);
|
||||
int sem_wait(sem_t* sem);
|
||||
/*int sem_timedwait (sem_t *sem, const struct timespec *abs_timeout);*/
|
||||
int sem_timedwait (sem_t *sem, unsigned int ticks);
|
||||
int sem_trywait(sem_t* sem);
|
||||
int sem_getvalue(sem_t* sem, int* sval);
|
||||
int sem_post(sem_t* sem);
|
||||
sem_t* sem_open(const char* name, int oflag, ...);
|
||||
int sem_unlink(const char* name);
|
||||
int sem_close(sem_t* sem);
|
||||
int sem_destroy(sem_t* sem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SEMAPHORE_H */
|
54
lib/bsp/xilkernel/src/include/sys/arch.h
Executable file
54
lib/bsp/xilkernel/src/include/sys/arch.h
Executable file
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file arch.h
|
||||
//! Includes architecture specific files into one single file (sys/arch.h)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _SYS_ARCH_H
|
||||
#define _SYS_ARCH_H
|
||||
|
||||
#include <os_config.h>
|
||||
|
||||
#ifdef MB_XILKERNEL
|
||||
#include <arch/microblaze/arch.h>
|
||||
#endif
|
||||
|
||||
#ifdef PPC_XILKERNEL
|
||||
#include <arch/ppc/arch.h>
|
||||
#ifndef __ASM__
|
||||
#include <xtime_l.h>
|
||||
#include <xil_exception.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif /* _SYS_ARCH_H */
|
64
lib/bsp/xilkernel/src/include/sys/bufmalloc.h
Executable file
64
lib/bsp/xilkernel/src/include/sys/bufmalloc.h
Executable file
|
@ -0,0 +1,64 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file bufmalloc.h
|
||||
//! Declarations and defines for block memory allocation API
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _BUFMALLOC_H
|
||||
#define _BUFMALLOC_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MEMBUF_ANY -1
|
||||
|
||||
typedef int membuf_t;
|
||||
|
||||
int sys_bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz);
|
||||
int sys_bufdestroy (membuf_t mbuf);
|
||||
void* sys_bufmalloc (membuf_t mbuf, size_t siz);
|
||||
void sys_buffree (membuf_t mbuf, void *mem);
|
||||
|
||||
int bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz);
|
||||
int bufdestroy (membuf_t mbuf);
|
||||
void* bufmalloc (membuf_t mbuf, size_t siz);
|
||||
void buffree (membuf_t mbuf, void *mem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BUFMALLOC_H */
|
93
lib/bsp/xilkernel/src/include/sys/decls.h
Executable file
93
lib/bsp/xilkernel/src/include/sys/decls.h
Executable file
|
@ -0,0 +1,93 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file decls.h
|
||||
//! Gathers declarations for kernel data structures in one place
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _SYS_DECLS_H
|
||||
#define _SYS_DECLS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char kernel_irq_stack[];
|
||||
extern char process_startup_stack[];
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ktypes.h>
|
||||
|
||||
extern pid_t current_pid, prev_pid, idle_task_pid;
|
||||
extern process_struct *current_process;
|
||||
extern process_struct ptable[];
|
||||
extern reent_t reent;
|
||||
extern void *_stack, __stack;
|
||||
extern struct _queue ready_q[];
|
||||
extern void *kernel_sp;
|
||||
extern pid_t idle_task_pid;
|
||||
|
||||
extern void _ftext __attribute__((weak)),
|
||||
_etext __attribute__((weak)),
|
||||
_fdata __attribute__((weak)),
|
||||
_edata __attribute__((weak)),
|
||||
_frodata __attribute__((weak)),
|
||||
_erodata __attribute__((weak)),
|
||||
_stack_end __attribute__((weak)),
|
||||
__stack __attribute__((weak));
|
||||
|
||||
extern void _fstack_guard_top __attribute__((weak)),
|
||||
_estack_guard_top __attribute__((weak)),
|
||||
_fstack_guard_bottom __attribute__((weak)),
|
||||
_estack_guard_bottom __attribute__((weak));
|
||||
|
||||
extern void idle_task (void);
|
||||
|
||||
#define kerrno (current_process->reent._errno)
|
||||
|
||||
#ifdef VERBOSE
|
||||
#define DBG_PRINT(string) print(string)
|
||||
#define DPUTNUM(num) putnum(num)
|
||||
#define DPRINTF xil_printf
|
||||
#else
|
||||
#define DBG_PRINT(string) // nothing
|
||||
#define DPUTNUM(num) // nothing
|
||||
#define DPRINTF(...) // nothing
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_DECLS_H */
|
46
lib/bsp/xilkernel/src/include/sys/entry.h
Executable file
46
lib/bsp/xilkernel/src/include/sys/entry.h
Executable file
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file entry.h
|
||||
//! Kernel entry related defines
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _SYS_ENTRY_H
|
||||
#define _SYS_ENTRY_H
|
||||
|
||||
|
||||
#define ENTRY_MODE_KERNEL 1
|
||||
#define ENTRY_MODE_USER 0
|
||||
|
||||
|
||||
#endif /* _SYS_ENTRY_H */
|
100
lib/bsp/xilkernel/src/include/sys/init.h
Executable file
100
lib/bsp/xilkernel/src/include/sys/init.h
Executable file
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file init.h
|
||||
//! This files contains structures, that are used for configuring the system.
|
||||
//! The values are specified in sys/init.c
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _INIT_H
|
||||
#define _INIT_H
|
||||
|
||||
#include <config/config_cparam.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/ktypes.h>
|
||||
#ifdef __MICROBLAZE__
|
||||
#include <sys/mpu.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! Processes to be initialised at the start of the system are defined here.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
struct _process_init {
|
||||
unsigned int p_start_addr ; // Start address of the process
|
||||
int priority ; // Priority of the process
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! Threads to be a part of kernel executable to be initialised at the start of the
|
||||
//! system are defined here.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
struct _elf_pthread_init {
|
||||
void (*start_func)(void); // Start address of the thread
|
||||
int priority ; // Priority of the thread
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! The shared memory in the system are defined here.
|
||||
//! There is a entry for each Shared Memory
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
struct _shm_init {
|
||||
unsigned int shm_size ; // Size of the Shared Memory
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! The dynamic memory (buffer) management module is configured here.
|
||||
//! The system can have memory blocks of different sizes. Memory blocks of
|
||||
//! different size and the number of memory blocks is specified here.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
typedef struct bufmalloc_init_s {
|
||||
unsigned int bsiz; // Memory Block size
|
||||
char nblks; // Number of blocks of the size
|
||||
} bufmalloc_init_t;
|
||||
|
||||
void soft_tmr_init(void);
|
||||
void pthread_init(void);
|
||||
void bufmalloc_init(void);
|
||||
void hw_init(void);
|
||||
int xmk_add_static_thread(void* (*start_routine)(void *), int sched_priority);
|
||||
void xilkernel_init (void);
|
||||
void xilkernel_start (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INIT_H */
|
52
lib/bsp/xilkernel/src/include/sys/intr.h
Executable file
52
lib/bsp/xilkernel/src/include/sys/intr.h
Executable file
|
@ -0,0 +1,52 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2004 Xilinx, Inc. All rights reserved.
|
||||
//
|
||||
// Xilinx, Inc.
|
||||
// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||
// COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||
// ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||
// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||
// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||
// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||
// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||
// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||
// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||
// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $Id: intr.h,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mem.h
|
||||
//! Kernel level memory allocation definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _INTR_H
|
||||
#define _INTR_H
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned char int_id_t;
|
||||
|
||||
unsigned int register_int_handler (int_id_t intr_id, void (*handler)(void*), void *callback);
|
||||
void unregister_int_handler (int_id_t intr_id);
|
||||
void enable_interrupt (int_id_t intr_id);
|
||||
void disable_interrupt (int_id_t intr_id);
|
||||
void acknowledge_interrupt (int_id_t intr_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _INTR_H */
|
59
lib/bsp/xilkernel/src/include/sys/ipc.h
Executable file
59
lib/bsp/xilkernel/src/include/sys/ipc.h
Executable file
|
@ -0,0 +1,59 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file ipc.h
|
||||
//! Standard POSIX IPC defines and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _IPC_H
|
||||
#define _IPC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IPC_CREAT 1 // Create entry if key does not exist.
|
||||
#define IPC_EXCL 2 // Fail if key exists.
|
||||
#define IPC_NOWAIT 3 // Error if request must wait
|
||||
|
||||
#define IPC_SET 1 // Set Options
|
||||
#define IPC_STAT 1 // Get Options
|
||||
#define IPC_RMID 2 // Remove identifier
|
||||
|
||||
#define IPC_PRIVATE 0xffffffff // Private key (Large value greater than any value possible for key)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _IPC_H */
|
62
lib/bsp/xilkernel/src/include/sys/kmsg.h
Executable file
62
lib/bsp/xilkernel/src/include/sys/kmsg.h
Executable file
|
@ -0,0 +1,62 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file kmsg.h
|
||||
//! Kernel message queue definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KMSG_H
|
||||
#define _KMSG_H
|
||||
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MSGQ_MAX_BYTES 100
|
||||
|
||||
// System calls
|
||||
int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf);
|
||||
int sys_msgget(key_t key, int msgflg);
|
||||
ssize_t sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
|
||||
int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KMSG_H */
|
108
lib/bsp/xilkernel/src/include/sys/kpthread.h
Executable file
108
lib/bsp/xilkernel/src/include/sys/kpthread.h
Executable file
|
@ -0,0 +1,108 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file kpthread.h
|
||||
//! Kernel pthread declarations and definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _KPTHREAD_H
|
||||
#define _KPTHREAD_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Defines
|
||||
|
||||
#define PTHREAD_INVALID 0xFF
|
||||
#define PTHREAD_MUTEX_INVALID 0xFFFF
|
||||
// Sched state
|
||||
#define PTHREAD_STATE_ALIVE 1
|
||||
#define PTHREAD_STATE_EXIT 2
|
||||
#define PTHREAD_STATE_DETACHED 3
|
||||
#define PTHREAD_STATE_BLOCKED 4
|
||||
|
||||
void pthread_terminate (pthread_info_t *thread);
|
||||
|
||||
// pthreads - Kernel implementation
|
||||
int sys_pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_func)(void*), void *param);
|
||||
void sys_pthread_exit (void *retval) ;
|
||||
int sys_pthread_join (pthread_t target, void **retval);
|
||||
pthread_t sys_pthread_self (void);
|
||||
int sys_pthread_detach (pthread_t thread);
|
||||
int sys_pthread_equal (pthread_t thread_1, pthread_t thread_2);
|
||||
int pthread_attr_init (pthread_attr_t *attr);
|
||||
int pthread_attr_destroy (pthread_attr_t *attr);
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
int pthread_attr_setschedparam (pthread_attr_t *attr,
|
||||
const struct sched_param *spar);
|
||||
int pthread_attr_getschedparam (const pthread_attr_t *attr,
|
||||
struct sched_param *spar);
|
||||
#endif
|
||||
|
||||
int pthread_attr_getdetachstate (const pthread_attr_t *attr, int *dstate);
|
||||
int pthread_attr_setdetachstate (pthread_attr_t *attr, int dstate);
|
||||
int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
|
||||
size_t *stacksize);
|
||||
int pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
|
||||
size_t stacksize);
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
int sys_pthread_mutex_init (pthread_mutex_t *mutex,
|
||||
const pthread_mutexattr_t *attr);
|
||||
int sys_pthread_mutex_destroy (pthread_mutex_t *mutex);
|
||||
int sys_pthread_mutex_lock (pthread_mutex_t *mutex);
|
||||
int sys_pthread_mutex_trylock (pthread_mutex_t *mutex);
|
||||
int sys_pthread_mutex_unlock (pthread_mutex_t *mutex);
|
||||
int pthread_mutexattr_init (pthread_mutexattr_t *attr);
|
||||
int pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
|
||||
#endif
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
int sys_pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param);
|
||||
int sys_pthread_setschedparam (pthread_t thread, int policy, struct sched_param *param);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KPTHREAD_H */
|
86
lib/bsp/xilkernel/src/include/sys/ksched.h
Executable file
86
lib/bsp/xilkernel/src/include/sys/ksched.h
Executable file
|
@ -0,0 +1,86 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file ksched.h
|
||||
//! Kernel level scheduling definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KSCHED_H
|
||||
#define _KSCHED_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/sched.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Scheduling algorithm.
|
||||
#ifndef SCHED_OTHER
|
||||
#define SCHED_OTHER 0 // Other
|
||||
#endif
|
||||
#ifndef SCHED_FIFO
|
||||
#define SCHED_FIFO 1 // FIFO scheduling
|
||||
#endif
|
||||
#ifndef SCHED_RR
|
||||
#define SCHED_RR 2 // Round Robin Scheduling type
|
||||
#endif
|
||||
|
||||
// This will go away in the future
|
||||
#define SCHED_PRIO 3 // Priority Preemptive Scheduling type
|
||||
|
||||
|
||||
void readyq_init(void) ;
|
||||
void process_scheduler(void) ;
|
||||
void process_scheduler_and_switch (void);
|
||||
void suspend (void);
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
void sched_rr (void);
|
||||
#elif SCHED_TYPE == SCHED_PRIO
|
||||
void sched_prio(void);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MB_XILKERNEL
|
||||
#define XMK_CONTEXT_SWITCH(prevpid) microblaze_context_switch(prevpid)
|
||||
#else // PPC
|
||||
#define XMK_CONTEXT_SWITCH(prevpid) ppc_context_switch(prevpid)
|
||||
#endif // MB_XILKERNEL
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KSCHED_H */
|
69
lib/bsp/xilkernel/src/include/sys/ksemaphore.h
Executable file
69
lib/bsp/xilkernel/src/include/sys/ksemaphore.h
Executable file
|
@ -0,0 +1,69 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file ksemaphore.h
|
||||
//! Kernel level semaphore definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KSEMAPHORE_H
|
||||
#define _KSEMAPHORE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int sys_sem_init(sem_t* sem, int pshared, unsigned value);
|
||||
sem_t* sys_sem_open(const char* name, int oflag, mode_t mode, unsigned value);
|
||||
int sys_sem_close(sem_t* sem);
|
||||
int sys_sem_unlink(const char* name);
|
||||
int sys_sem_getvalue(sem_t* sem, int* sval);
|
||||
int sys_sem_wait_x(sem_t* sem);
|
||||
int sys_sem_trywait(sem_t *sem);
|
||||
int sys_sem_post(sem_t* sem);
|
||||
int sys_sem_destroy(sem_t* sem);
|
||||
int sem_force_destroy (sem_t* sem);
|
||||
|
||||
void sem_heap_init(void);
|
||||
sem_info_t* get_sem_by_semt( sem_t* sem);
|
||||
sem_info_t* get_sem_by_name( char* sem);
|
||||
sem_t* get_semt_by_name( char* name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KSEMAPHORE_H */
|
59
lib/bsp/xilkernel/src/include/sys/kshm.h
Executable file
59
lib/bsp/xilkernel/src/include/sys/kshm.h
Executable file
|
@ -0,0 +1,59 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file kshm.h
|
||||
//! Kernel level shared memory declarations and definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KSHM_H
|
||||
#define _KSHM_H
|
||||
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// SHM system calls
|
||||
int sys_shmget (key_t key, size_t size, int shmflg);
|
||||
int sys_shmctl (int shmid, int cmd, struct shmid_ds* buf);
|
||||
void* sys_shmat (int shmid, const void *shmaddr, int shmflg);
|
||||
int sys_shmdt (const void *shmaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KSHM_H */
|
177
lib/bsp/xilkernel/src/include/sys/ktypes.h
Executable file
177
lib/bsp/xilkernel/src/include/sys/ktypes.h
Executable file
|
@ -0,0 +1,177 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file ktypes.h
|
||||
//! Kernel equivalent of sys/types.h
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _KTYPES_H
|
||||
#define _KTYPES_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/types.h>
|
||||
#include <semaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SET_CURRENT_PROCESS(pid) do { \
|
||||
current_pid = pid; \
|
||||
current_process = (pid == -1) ? NULL:(&ptable[pid]); \
|
||||
} while(0)
|
||||
|
||||
typedef struct _process_struct process_struct ;
|
||||
typedef struct _process_context process_context ;
|
||||
|
||||
struct pthread_info_s;
|
||||
// Queue Management Data Structures
|
||||
typedef struct _queue *queuep ;
|
||||
|
||||
struct _queue {
|
||||
unsigned short item_size ; //! Size of Queue item
|
||||
unsigned char max_items ; //! Max. number of items in Q
|
||||
unsigned char item_count ; //! Items in the Queue
|
||||
unsigned char qfront ; //! Queue front pointer
|
||||
unsigned char qend ; //! Queue end pointer
|
||||
void *items ; //! Queue of item's
|
||||
};
|
||||
|
||||
typedef struct reent_s {
|
||||
int _errno;
|
||||
} reent_t;
|
||||
|
||||
//! Process Control Block - Information about the Process
|
||||
struct _process_struct {
|
||||
process_context pcontext; //! Context switch store. Keep this at the top of the structure. Context switch relies on this.
|
||||
unsigned char state; //! Process State
|
||||
pid_t pid; //! Unique Process Identifier
|
||||
signed char priority; //! Process Priority
|
||||
signed char is_allocated; //! If the PCB has been allocated
|
||||
//! 0 - Unallocated, 1 - Allocated
|
||||
queuep blockq; //! Queue on which this process is currently blocked
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
struct pthread_info_s* thread; //! Pointer to the thread that is currently using this PCB.
|
||||
//! Kludge ! Used because process and threads are essentially the same now.
|
||||
#endif
|
||||
#ifdef CONFIG_TIME
|
||||
unsigned char timeout; //! Flag set if this process had a recent timeout
|
||||
unsigned int remain; //! Number of milliseconds of timeout remaining when this process was unblocked
|
||||
#endif
|
||||
#ifdef CONFIG_STATS
|
||||
unsigned int active_ticks; //! Number of quantums which this process has executed (approx)
|
||||
#endif
|
||||
reent_t reent; //! Re-entrancy information for this process
|
||||
} __attribute__ ((aligned (4), packed));
|
||||
|
||||
//! Kernel pthread info structure
|
||||
typedef struct pthread_info_s {
|
||||
char is_allocated;
|
||||
process_struct *parent; //! pointer back to base process structure
|
||||
pthread_t tid; //! ID of this thread.
|
||||
void *retval; //! Return value of thread when it terminates.
|
||||
void* (*start_func)(void*); //! Starting function
|
||||
void *param; //! Parameter to starting function
|
||||
unsigned char state; //! Thread state
|
||||
struct pthread_info_s *join_thread; //! Joining thread
|
||||
char joinq_mem; //! Just a single byte of memory for the queue
|
||||
struct _queue joinq; //! Queue of size 1.
|
||||
signed char mem_id ; //! Mem ID of thread context
|
||||
pthread_attr_t thread_attr; //! Thread attributes
|
||||
} pthread_info_t;
|
||||
|
||||
|
||||
//! Kernel mutex info structure
|
||||
typedef struct pthread_mutexinfo_s {
|
||||
int is_allocated;
|
||||
int locked;
|
||||
pthread_mutexattr_t attr; //! Mutex attributes
|
||||
struct _queue mutex_wait_q ; //! Queue of waiting threads
|
||||
pid_t owner; //! ID of currently locking process
|
||||
} pthread_mutexinfo_t;
|
||||
|
||||
|
||||
//! Kernel semaphore info structure
|
||||
typedef struct sem_info_s {
|
||||
signed char sem_id; //! Semaphore ID. -1 -> uninitialized
|
||||
signed char sem_value; //! Resource count
|
||||
struct _queue sem_wait_q ; //! Queue of waiting processes
|
||||
pid_t owner; //! PID of process owning this semaphore. if -1 ,
|
||||
//! then any process can access this sem.
|
||||
unsigned char unlink; //! Unlink status
|
||||
} sem_info_t;
|
||||
|
||||
//! Semaphore symbolic name mapping table
|
||||
typedef struct sem_map_s {
|
||||
char name[SEM_NAME_MAX];
|
||||
sem_t sem;
|
||||
} sem_map_t;
|
||||
|
||||
//! Message queue buffer structure
|
||||
typedef struct msg_s {
|
||||
char* msg_buf;
|
||||
size_t msg_len;
|
||||
} msg_t;
|
||||
|
||||
//! Kernel message queue info structure
|
||||
typedef struct msgid_s {
|
||||
int msgid ; //! Message Queue ID
|
||||
key_t key ; //! Key used to identify the MsgQ
|
||||
//unsigned char msgsize ; //! The size of the Message
|
||||
unsigned char msgq_len ; //! Message Queue depth
|
||||
sem_t full ; //! Semaphore used by the producer
|
||||
sem_t empty ; //! Semaphore used by the consumer
|
||||
struct _queue msg_q ; //! Queue of Messages
|
||||
struct msqid_ds stats; //! Statistics about message queue
|
||||
} msgid_ds;
|
||||
|
||||
|
||||
//! Kernel shared memory info structure
|
||||
typedef struct shm_info_s {
|
||||
size_t shm_segsz; //! Size of segment in bytes.
|
||||
pid_t shm_lpid; //! Process ID of last shared memory operation.
|
||||
pid_t shm_cpid; //! Process ID of creator.
|
||||
shmatt_t shm_nattch; //! Number of current attaches.
|
||||
void* shm_addr; //! Shared memory pointer
|
||||
int shm_id; //! ID of this SHM struct
|
||||
key_t shm_key; //! Associated key
|
||||
} shm_info_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _KTYPES_H
|
78
lib/bsp/xilkernel/src/include/sys/mem.h
Executable file
78
lib/bsp/xilkernel/src/include/sys/mem.h
Executable file
|
@ -0,0 +1,78 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mem.h
|
||||
//! Kernel level memory allocation definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _SYS_MEM_H
|
||||
#define _SYS_MEM_H
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SEMQ_START (N_PRIO*MAX_READYQ)
|
||||
|
||||
//! This is used by buffer management routines.
|
||||
//! Each Memory Block of different sizes is associated with each structure
|
||||
struct _malloc_info {
|
||||
unsigned int mem_bsize ; //! Memory Block Size
|
||||
unsigned char max_blks ; //! Max. number of mem blocks
|
||||
unsigned char n_blks ; //! No. of mem blocks allocated
|
||||
unsigned short start_blk ; //! The starting mem. blk number
|
||||
signed char *start_addr ; //! Starting memory location for this bll
|
||||
};
|
||||
|
||||
void alloc_pidq_mem( queuep queue, unsigned int qtype, unsigned int qno ) ;
|
||||
int se_process_init(void) ;
|
||||
int kb_pthread_init(void);
|
||||
void alloc_msgq_mem( queuep queue, unsigned int qno ) ;
|
||||
void msgq_init(void) ;
|
||||
void shm_init(void) ;
|
||||
void bss_mem_init(void) ;
|
||||
int alloc_bss_mem( unsigned int *start, unsigned int *end ) ;
|
||||
void free_bss_mem( unsigned int memid ) ;
|
||||
void malloc_init(void) ;
|
||||
void sem_heap_init(void);
|
||||
void bufmalloc_mem_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_MEM_H */
|
65
lib/bsp/xilkernel/src/include/sys/mpu.h
Executable file
65
lib/bsp/xilkernel/src/include/sys/mpu.h
Executable file
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mpu.h
|
||||
//! Memory protection related declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _MPU_H
|
||||
#define _MPU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MPU_PROT_EXEC 0x200
|
||||
#define MPU_PROT_READWRITE 0x100
|
||||
#define MPU_PROT_READ 0x0
|
||||
#define MPU_PROT_NONE 0x0
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! The I/O ranges that must be initialized when an MPU is enabled are configured here.
|
||||
//! These I/O ranges will not include "memory" ranges.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
typedef struct xilkernel_io_range_s {
|
||||
unsigned int baseaddr;
|
||||
unsigned int highaddr;
|
||||
unsigned int flags;
|
||||
} xilkernel_io_range_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MPU_H
|
70
lib/bsp/xilkernel/src/include/sys/msg.h
Executable file
70
lib/bsp/xilkernel/src/include/sys/msg.h
Executable file
|
@ -0,0 +1,70 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file msg.h
|
||||
//! Standard POSIX Message queue definitions and declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _MSG_H
|
||||
#define _MSG_H
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MSG_NOERROR 1
|
||||
|
||||
|
||||
typedef unsigned int msgqnum_t;
|
||||
typedef unsigned int msglen_t;
|
||||
|
||||
struct msqid_ds {
|
||||
//struct ipc_perm msg_perm;
|
||||
msgqnum_t msg_qnum; // Number of messages in the Q
|
||||
msglen_t msg_qbytes; // Total number of bytes in the Q
|
||||
pid_t msg_lspid; // Process ID of last msgsnd().
|
||||
pid_t msg_lrpid; // Process ID of last msgrcv ().
|
||||
};
|
||||
|
||||
int msgctl (int msgid, int cmd, struct msqid_ds *buf);
|
||||
int msgget (key_t key, int msgflg);
|
||||
ssize_t msgrcv (int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
|
||||
int msgsnd (int msgid, const void *msgp, size_t msgsz, int msgflg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _MSG_H
|
91
lib/bsp/xilkernel/src/include/sys/process.h
Executable file
91
lib/bsp/xilkernel/src/include/sys/process.h
Executable file
|
@ -0,0 +1,91 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file process.h
|
||||
//! Process management declarations and definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _PROCESS_H_
|
||||
#define _PROCESS_H_
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/stats.h>
|
||||
#include <sys/kpthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//! Process States.
|
||||
#define PROC_NEW 0 //! Process is new and has not been scheduled yet
|
||||
#define PROC_RUN 1 //! Process is currently executing
|
||||
#define PROC_READY 2 //! Process that is ready and considered for scheduling
|
||||
#define PROC_WAIT 3 //! Process is waiting for a resource. Is out of ready queues and in some wait queue
|
||||
#define PROC_TIMED_WAIT 4 //! Process is waiting for a resource with a timeout. Is out of ready queues and in some wait queue
|
||||
#define PROC_DELAY 5 //! Process is waiting for a timeout
|
||||
#define PROC_DEAD 6 //! State of process that has called exit and is now "dead"
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Function prototypes - defined in sys/process.h
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Internal Kernel functions. These routines are not directly called from any
|
||||
// process. They don't have reentrant code.
|
||||
|
||||
void xmk_enter_kernel (void);
|
||||
void xmk_leave_kernel (void);
|
||||
void process_block (queuep queue, unsigned int state) ;
|
||||
void process_unblock( queuep queue ) ;
|
||||
pid_t proc_create (unsigned int priority);
|
||||
int process_invalidate (process_struct *proc);
|
||||
|
||||
pid_t sys_elf_process_create (void* pstart_addr, unsigned int priority);
|
||||
int sys_elf_exit (void);
|
||||
int sys_kill (pid_t pid);
|
||||
int sys_process_status (pid_t pid, p_stat *ps);
|
||||
int sys_yield(void);
|
||||
pid_t sys_get_currentPID(void);
|
||||
int sys_get_kernel_stats (kstats_t *stats);
|
||||
|
||||
|
||||
pid_t get_currentPID(void);
|
||||
int kill (pid_t pid);
|
||||
int process_status (pid_t pid, p_stat *ps);
|
||||
int yield(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PROCESS_H_ */
|
74
lib/bsp/xilkernel/src/include/sys/queue.h
Executable file
74
lib/bsp/xilkernel/src/include/sys/queue.h
Executable file
|
@ -0,0 +1,74 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file queue.h
|
||||
//! Queue management declarations and defines
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _QUEUE_H
|
||||
#define _QUEUE_H
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//! Queue Types
|
||||
#define RUN_Q 1 //! Used to store Processes in PROC_RUN state
|
||||
#define READY_Q 2 //! Used to store Processes in PROC_READY state
|
||||
#define SEM_Q 3 //! Used for storing processes waiting for semaphore resource
|
||||
#define MSG_Q 4 //! Used for storing Messages in Message Q
|
||||
#define PTHREAD_JOIN_Q 5 //! Used for storing Threads waiting to join in a join Q
|
||||
#define PTHREAD_EXIT_Q 6 //! Used for storing Threads in state PTHREAD_STATE_EXIT
|
||||
#define PTHREAD_MUTEX_Q 7 //! Used for storing processes waiting for mutex resource
|
||||
|
||||
// Function prototypes defined in sys/queue.c
|
||||
void alloc_q (queuep queue, unsigned char max_items,
|
||||
unsigned char qtype, unsigned short size, unsigned char qno);
|
||||
void qinit (queuep queue);
|
||||
void enq (queuep queue, const void *item, unsigned short key);
|
||||
void deq (queuep queue, void *item, unsigned short key);
|
||||
int pdelq (queuep queue, pid_t item);
|
||||
void pdeq (queuep queue, pid_t *item, unsigned short key);
|
||||
void penq (queuep queue, pid_t item, unsigned short key);
|
||||
void prio_penq (queuep queue, pid_t item, unsigned short key);
|
||||
void prio_pdeq (queuep queue, pid_t *item, unsigned short key);
|
||||
int prio_pdelq (queuep queue, pid_t item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _QUEUE_H */
|
80
lib/bsp/xilkernel/src/include/sys/shm.h
Executable file
80
lib/bsp/xilkernel/src/include/sys/shm.h
Executable file
|
@ -0,0 +1,80 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file shm.h
|
||||
//! Standard POSIX Shared memory declarations and definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _SHM_H
|
||||
#define _SHM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHM_RDONLY 1 // Attach read-only (else read-write).
|
||||
#define SHM_RND 2 // Round attach address to SHMLBA.
|
||||
|
||||
#define SHMLBA 4 // Segment low boundary address multiple.
|
||||
|
||||
|
||||
|
||||
typedef unsigned int shmatt_t;
|
||||
|
||||
// Each Shared Memory is associated with this structure.
|
||||
// @Note: shmid_ds not fully posix compliant.
|
||||
// Commented out fields unsupported.
|
||||
struct shmid_ds {
|
||||
//struct ipc_perm shm_perm; // Operation permission structure.
|
||||
size_t shm_segsz; // Size of segment in bytes.
|
||||
pid_t shm_lpid; // Process ID of last shared memory operation.
|
||||
pid_t shm_cpid; // Process ID of creator.
|
||||
shmatt_t shm_nattch; // Number of current attaches.
|
||||
//time_t shm_atime; // Time of last shmat ().
|
||||
//time_t shm_dtime; // Time of last shmdt ().
|
||||
//time_t shm_ctime ; // Time of last change by shmctl ().
|
||||
};
|
||||
|
||||
int shmget (key_t key, size_t size, int shmflg);
|
||||
int shmctl (int shmid, int cmd, struct shmid_ds* buf);
|
||||
void* shmat (int shmid, const void *shmaddr, int shmflg);
|
||||
int shmdt (const void *shmaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SHM_H */
|
70
lib/bsp/xilkernel/src/include/sys/stats.h
Executable file
70
lib/bsp/xilkernel/src/include/sys/stats.h
Executable file
|
@ -0,0 +1,70 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file stats.h
|
||||
//! Kernel statistics collection definitions and structures
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _STATS_H
|
||||
#define _STATS_H
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/ktypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SCHED_HISTORY_SIZ 25
|
||||
|
||||
//! Process Status structure used for process_status
|
||||
typedef struct _ps_stat{
|
||||
pid_t pid ; //! Process ID
|
||||
unsigned char state ; //! State of process
|
||||
unsigned long aticks; //! Active ticks
|
||||
signed char priority; //! Process priority
|
||||
} p_stat;
|
||||
|
||||
//! Kernel statistics structure
|
||||
typedef struct kstats_s {
|
||||
unsigned int kernel_ticks;
|
||||
pid_t sched_history[SCHED_HISTORY_SIZ];
|
||||
int pstat_count;
|
||||
p_stat *pstats;
|
||||
} kstats_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _STATS_H */
|
163
lib/bsp/xilkernel/src/include/sys/syscall.h
Executable file
163
lib/bsp/xilkernel/src/include/sys/syscall.h
Executable file
|
@ -0,0 +1,163 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file syscall.h
|
||||
//! The System call numbers for the system are defined here. These numbers
|
||||
//! are then used to index into the system call vector table by the system
|
||||
//! call handler, when a system call is invoked.
|
||||
//!
|
||||
//! The system calls are available for following routines
|
||||
//! - Process Management
|
||||
//! - Thread Managament
|
||||
//! - Semaphore
|
||||
//! - Message Queue
|
||||
//! - Shared Memory
|
||||
//! - Dynamic Buffer Management
|
||||
//! - XilNet
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _SYSCALL_H
|
||||
#define _SYSCALL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SC_PROCESS_CREATE 1 // Process Management
|
||||
#define SC_PROCESS_EXIT 2
|
||||
#define SC_PROCESS_KILL 3
|
||||
#define SC_PROCESS_STATUS 4
|
||||
#define SC_GET_REENTRANCY 5
|
||||
#define SC_PROCESS_YIELD 6
|
||||
#define SC_PROCESS_GETPID 7
|
||||
#define SC_PROCESS_GETPRIORITY 8
|
||||
#define SC_PROCESS_SETPRIORITY 9
|
||||
|
||||
#define SC_PTHREAD_CREATE 10 // Thread Management
|
||||
#define SC_PTHREAD_EXIT 11
|
||||
#define SC_PTHREAD_JOIN 12
|
||||
#define SC_PTHREAD_SELF 13
|
||||
#define SC_PTHREAD_DETACH 14
|
||||
#define SC_PTHREAD_EQUAL 15
|
||||
#define SC_PTHREAD_GETSCHEDPARAM 16
|
||||
#define SC_PTHREAD_SETSCHEDPARAM 17
|
||||
#define SC_PTHREAD_MUTEX_INIT 18 // Pthread Mutex handling
|
||||
#define SC_PTHREAD_MUTEX_LOCK 19
|
||||
#define SC_PTHREAD_MUTEX_TRYLOCK 20
|
||||
#define SC_PTHREAD_MUTEX_UNLOCK 21
|
||||
#define SC_PTHREAD_MUTEX_DESTROY 22
|
||||
#define SC_PTHREAD_RESERVED_0 23
|
||||
#define SC_PTHREAD_RESERVED_1 24
|
||||
#define SC_PTHREAD_RESERVED_2 25
|
||||
#define SC_PTHREAD_RESERVED_3 26
|
||||
#define SC_PTHREAD_RESERVED_4 27
|
||||
#define SC_PTHREAD_RESERVED_5 28
|
||||
#define SC_PTHREAD_RESERVED_6 29
|
||||
|
||||
#define SC_SEM_INIT 30 // Semaphore
|
||||
#define SC_SEM_WAIT 31
|
||||
#define SC_SEM_TRYWAIT 32
|
||||
#define SC_SEM_POST 33
|
||||
#define SC_SEM_DESTROY 34
|
||||
#define SC_SEM_OPEN 35
|
||||
#define SC_SEM_CLOSE 36
|
||||
#define SC_SEM_UNLINK 37
|
||||
#define SC_SEM_GETVALUE 38
|
||||
#define SC_SEM_TIMED_WAIT 39
|
||||
#define SC_SEM_RESERVED_1 40
|
||||
|
||||
#define SC_MSGGET 41 // Message Queue
|
||||
#define SC_MSGCTL 42
|
||||
#define SC_MSGSND 43
|
||||
#define SC_MSGRCV 44
|
||||
#define SC_MSG_RESERVED_0 45
|
||||
|
||||
#define SC_SHMGET 46 // Shared Memory
|
||||
#define SC_SHMCTL 47
|
||||
#define SC_SHMAT 48
|
||||
#define SC_SHMDT 49
|
||||
|
||||
|
||||
#define SC_BUFCREATE 50 // Dynamic Buffer Management
|
||||
#define SC_BUFDESTROY 51
|
||||
#define SC_BUFMALLOC 52
|
||||
#define SC_BUFFREE 53
|
||||
#define SC_MALLOC_RESERVED_2 54
|
||||
|
||||
#define SC_TMR_GETCLOCKTICKS 55
|
||||
#define SC_TMR_SLEEP 56 // Software timers
|
||||
#define SC_TMR_TIME 57
|
||||
|
||||
#define SC_REGISTER_INT_HANDLER 58 // User level interrupt handlers
|
||||
#define SC_UNREGISTER_INT_HANDLER 59
|
||||
#define SC_ENABLE_INTERRUPT 60
|
||||
#define SC_DISABLE_INTERRUPT 61
|
||||
#define SC_ACKNOWLEDGE_INTERRUPT 62
|
||||
|
||||
//#define SC_RESERVED_0 63
|
||||
#define SC_GET_KERNEL_STATS 63
|
||||
#define SC_RESERVED_1 64
|
||||
#define SC_RESERVED_2 65
|
||||
#define SC_RESERVED_3 66
|
||||
#define SC_RESERVED_4 67
|
||||
#define SC_RESERVED_5 68
|
||||
#define SC_RESERVED_6 69
|
||||
#define SC_RESERVED_7 70
|
||||
#define SC_RESERVED_8 71
|
||||
#define SC_RESERVED_9 72
|
||||
|
||||
#define SC_XILSOCK_SOCKET 73 // Xil Net
|
||||
#define SC_XILSOCK_BIND 74
|
||||
#define SC_XILSOCK_LISTEN 75
|
||||
#define SC_XILSOCK_ACCEPT 76
|
||||
#define SC_XILSOCK_RECV 77
|
||||
#define SC_XILSOCK_SEND 78
|
||||
#define SC_XILSOCK_RECVFROM 79
|
||||
#define SC_XILSOCK_SENDTO 80
|
||||
#define SC_XILSOCK_CLOSE 81
|
||||
|
||||
struct t_syscall_data {
|
||||
int system_call_num; // predefined system call number
|
||||
// actual function to be called will be passed these params
|
||||
void *param1;
|
||||
void *param2;
|
||||
void *param3;
|
||||
void *param4;
|
||||
void *param5;
|
||||
void *param6;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSCALL_H */
|
71
lib/bsp/xilkernel/src/include/sys/timer.h
Executable file
71
lib/bsp/xilkernel/src/include/sys/timer.h
Executable file
|
@ -0,0 +1,71 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file timer.h
|
||||
//! Declarations and defines for timer related functionality
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _TIMER_H
|
||||
#define _TIMER_H
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct soft_tmr_s {
|
||||
unsigned int timeout;
|
||||
pid_t pid;
|
||||
} soft_tmr_t;
|
||||
|
||||
void soft_tmr_init(void) ;
|
||||
int add_tmr (pid_t pid, unsigned ticks);
|
||||
unsigned
|
||||
int remove_tmr (pid_t pid);
|
||||
void soft_tmr_handler (void);
|
||||
unsigned
|
||||
int xget_clock_ticks (void);
|
||||
|
||||
unsigned
|
||||
int sys_xget_clock_ticks (void);
|
||||
time_t sys_time (time_t *timer);
|
||||
unsigned sys_sleep (unsigned ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TIMER_H */
|
107
lib/bsp/xilkernel/src/include/sys/xtrace.h
Executable file
107
lib/bsp/xilkernel/src/include/sys/xtrace.h
Executable file
|
@ -0,0 +1,107 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file xtrace.h
|
||||
//! Kernel level trace API
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef _XTRACE_H
|
||||
#define _XTRACE_H
|
||||
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum xtrace_event {
|
||||
XSCHED_EVENT,
|
||||
XSEM_EVENT,
|
||||
XTIMER_EVENT,
|
||||
XCUSTOM_EVENT
|
||||
};
|
||||
|
||||
enum xtrace_action {
|
||||
XSCHED_RESCHED,
|
||||
XSEM_WAIT,
|
||||
XSEM_TIMEWAIT,
|
||||
XSEM_WAIT_TIMEOUT,
|
||||
XSEM_WAIT_UNBLOCK,
|
||||
XSEM_ACQUIRE,
|
||||
XSEM_POST,
|
||||
XSEM_POST_UNBLOCK,
|
||||
XTIMER_TIMEOUT,
|
||||
XTIMER_TICK,
|
||||
XTIMER_ADD,
|
||||
XTIMER_REMOVE,
|
||||
XCUSTOM_ACTION1,
|
||||
XCUSTOM_ACTION2,
|
||||
XCUSTOM_ACTION3,
|
||||
XCUSTOM_ACTION4,
|
||||
XCUSTOM_ACTION5,
|
||||
XCUSTOM_ACTION6
|
||||
};
|
||||
|
||||
typedef struct xtrace_pkt_s {
|
||||
enum xtrace_event event;
|
||||
pid_t pid;
|
||||
unsigned int resource;
|
||||
enum xtrace_action action;
|
||||
unsigned int custom[2];
|
||||
} xtrace_pkt_t;
|
||||
|
||||
void xtrace_log_event (enum xtrace_event event, enum xtrace_action action,
|
||||
unsigned int resource, unsigned int custom0, unsigned int custom1);
|
||||
void xtrace_print_log (void);
|
||||
|
||||
|
||||
#if 0
|
||||
#define CONFIG_XTRACE
|
||||
#define CONFIG_XTRACE_MEM_START 0x9a000000
|
||||
#define CONFIG_XTRACE_MAX_COUNT 100000
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CONFIG_XTRACE
|
||||
#undef xtrace_log_event
|
||||
#define xtrace_log_event(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _XTRACE_H */
|
56
lib/bsp/xilkernel/src/include/xmk.h
Executable file
56
lib/bsp/xilkernel/src/include/xmk.h
Executable file
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file xmk.h
|
||||
//! XMK primary declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifndef _XMK_H
|
||||
#define _XMK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __XMK__
|
||||
#define __XMK__
|
||||
#endif
|
||||
|
||||
/* Declarations */
|
||||
void xilkernel_main (void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _XMK_H
|
65
lib/bsp/xilkernel/src/src/Makefile
Executable file
65
lib/bsp/xilkernel/src/src/Makefile
Executable file
|
@ -0,0 +1,65 @@
|
|||
#############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# File : Makefile
|
||||
# Company: Xilinx
|
||||
#
|
||||
# Makefile for lib_src direcotry
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
SUBDIRS = dir_arch dir_sys dir_ipc
|
||||
|
||||
all: $(SUBDIRS)
|
||||
|
||||
|
||||
dir_arch:
|
||||
$(MAKE) -C arch/$(ARCH) CFLAGS="$(CFLAGS)" CC="$(CC)" AR="$(AR)"
|
||||
|
||||
dir_sys:
|
||||
$(MAKE) -C sys CFLAGS="$(CFLAGS)" CC="$(CC)" AR="$(AR)"
|
||||
|
||||
dir_ipc:
|
||||
$(MAKE) -C ipc CFLAGS="$(CFLAGS)" CC="$(CC)" AR="$(AR)"
|
||||
|
||||
clean:
|
||||
$(MAKE) -C sys clean
|
||||
$(MAKE) -C ipc clean
|
||||
$(MAKE) -C arch/$(ARCH) clean
|
59
lib/bsp/xilkernel/src/src/arch/microblaze/Makefile
Executable file
59
lib/bsp/xilkernel/src/src/arch/microblaze/Makefile
Executable file
|
@ -0,0 +1,59 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for sys direcotry
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
OBJS = entry.o timer_intr_handler.o mb-hw.o debugmon.o mpu.o hw_exception_handler.o
|
||||
INCLUDEDIR = ../../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -D__ASM__ -c $< -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~
|
148
lib/bsp/xilkernel/src/src/arch/microblaze/debugmon.c
Executable file
148
lib/bsp/xilkernel/src/src/arch/microblaze/debugmon.c
Executable file
|
@ -0,0 +1,148 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file debugmon.c
|
||||
//! Kernel inbuilt debug monitor routines for Microblaze
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/init.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/stats.h>
|
||||
|
||||
#ifdef CONFIG_DEBUGMON
|
||||
|
||||
extern signed char idle_task_pid;
|
||||
extern unsigned int budget_ticks;
|
||||
extern process_struct ptable[] ;
|
||||
extern signed char current_pid ;
|
||||
extern process_struct *current_process;
|
||||
extern process_struct *ctx_save_process;
|
||||
extern signed char prev_pid;
|
||||
extern struct _queue ready_q[] ;
|
||||
extern signed char entry_mode;
|
||||
extern signed char resched;
|
||||
|
||||
void debugmon_dump_proc_info (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
xmk_enter_kernel ();
|
||||
DBG_PRINT ("DEBUGMON: kernel_dump_proc_info ----> \r\n");
|
||||
for (i = 0; i<MAX_PROCESS_CONTEXTS; i++) {
|
||||
if (!ptable[i].is_allocated)
|
||||
continue;
|
||||
|
||||
DBG_PRINT ("=============================>\r\n");
|
||||
DBG_PRINT ("pid: ");
|
||||
putnum (ptable[i].pid);
|
||||
DBG_PRINT ("\r\nstate: ");
|
||||
putnum (ptable[i].state);
|
||||
DBG_PRINT ("\r\nisrflag: ");
|
||||
putnum (ptable[i].pcontext.isrflag);
|
||||
|
||||
for (j=0; j<33; j++) {
|
||||
DBG_PRINT ("\r\nregs[");
|
||||
putnum (j);
|
||||
DBG_PRINT ("]: ");
|
||||
putnum (ptable[i].pcontext.regs[j]);
|
||||
}
|
||||
DBG_PRINT ("\r\n=============================>\r\n\r\n");
|
||||
}
|
||||
DBG_PRINT ("DEBUGMON: kernel_dump_proc_info ENDS\r\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
void debugmon_stack_check (void)
|
||||
{
|
||||
unsigned int cur_sp;
|
||||
unsigned int saddr, ssize;
|
||||
|
||||
if (current_process->thread != NULL && current_process->thread->thread_attr.stackaddr != NULL) {
|
||||
cur_sp = current_process->pcontext.regs[1];
|
||||
saddr = (unsigned int) current_process->thread->thread_attr.stackaddr;
|
||||
ssize = current_process->thread->thread_attr.stacksize;
|
||||
|
||||
if ((cur_sp > saddr) || (cur_sp <= (saddr - ssize))) {
|
||||
DBG_PRINT ("DEBUGMON: Stack check failed for PID: ");
|
||||
putnum (current_process->pid);
|
||||
DBG_PRINT (", SP: ");
|
||||
putnum (current_process->pcontext.regs[1]);
|
||||
DBG_PRINT (", Base: ");
|
||||
putnum (saddr);
|
||||
DBG_PRINT (", Limit: ");
|
||||
putnum ((saddr - ssize));
|
||||
DBG_PRINT ("\r\n");
|
||||
debugmon_dump_proc_info ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void debugmon_dump_sched_info (void)
|
||||
{
|
||||
int i;
|
||||
char *qp;
|
||||
|
||||
print ("Scheduler: current_pid: ");
|
||||
putnum (current_pid);
|
||||
print (", prev_pid: ");
|
||||
putnum (prev_pid);
|
||||
print ("\r\n");
|
||||
|
||||
print ("ready_q[0].item_count: ");
|
||||
putnum(ready_q[0].item_count);
|
||||
print ("\r\n");
|
||||
qp = (char*)ready_q[0].items;
|
||||
qp += ready_q[0].qfront;
|
||||
|
||||
print ("Items: ( ");
|
||||
for (i=0; i<ready_q[0].item_count; i++) {
|
||||
putnum(*qp++);
|
||||
print (" ");
|
||||
}
|
||||
print (")\r\n");
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUGMON */
|
613
lib/bsp/xilkernel/src/src/arch/microblaze/entry.S
Executable file
613
lib/bsp/xilkernel/src/src/arch/microblaze/entry.S
Executable file
|
@ -0,0 +1,613 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! entry.S - Represents all the entry and exit points into the kernel
|
||||
//! i.e - System calls, Interrupts and Traps
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
*/
|
||||
#include <os_config.h>
|
||||
#include <sys/entry.h>
|
||||
#include <sys/arch.h>
|
||||
#include <xparameters.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
|
||||
.extern current_pid
|
||||
.extern entry_mode
|
||||
.extern resched
|
||||
.extern ptable
|
||||
.extern current_process, ctx_save_process /* Pointers to corresponding process control blocks */
|
||||
.extern XIntc_DeviceInterruptHandler
|
||||
.extern restore_kernel_context
|
||||
.extern timer_int_handler
|
||||
.extern pit_reset, pit_disable
|
||||
.extern kernel_irq_stack_ptr
|
||||
.extern kernel_irq_stack_ptr_end
|
||||
.extern proc_restore_state
|
||||
.extern syscall_table
|
||||
.extern microblaze_report_exception
|
||||
|
||||
#define NUM_TO_REG(num) r ## num
|
||||
#define REG_OFFSET(regnum) (4 * (regnum))
|
||||
|
||||
#define GET_CURRENT_PROC(reg) \
|
||||
lwi reg, r0, current_process;
|
||||
|
||||
#define GET_CTX_SAVE_PROC(reg) \
|
||||
lwi reg, r0, ctx_save_process;
|
||||
|
||||
/* Microblaze specific register's index in the context structure */
|
||||
#define MSR 32
|
||||
#define SHR_REG 33
|
||||
#define SLR_REG 34
|
||||
|
||||
#define PUSH_REG(regnum) \
|
||||
swi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
|
||||
|
||||
#define POP_REG(regnum) \
|
||||
lwi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
|
||||
|
||||
/* Uses r11 */
|
||||
#define CTX_SAVE_REG(regnum) \
|
||||
swi NUM_TO_REG(regnum), r11, CTX_REG_OFFSET(regnum)
|
||||
|
||||
/* Uses r11 */
|
||||
#define CTX_RESTORE_REG(regnum) \
|
||||
lwi NUM_TO_REG(regnum), r11, CTX_REG_OFFSET(regnum)
|
||||
|
||||
#define CTX_SAVE_SP \
|
||||
CTX_SAVE_REG(1);
|
||||
|
||||
#define CTX_RESTORE_SP \
|
||||
CTX_RESTORE_REG(1);
|
||||
|
||||
#define CTX_SAVE_LR \
|
||||
CTX_SAVE_REG(15);
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
|
||||
#define CTX_SAVE_STACK_HIGH_REG \
|
||||
mfs r12, rshr; \
|
||||
swi r12, r11, CTX_REG_OFFSET(SHR_REG);
|
||||
|
||||
#define CTX_SAVE_STACK_LOW_REG \
|
||||
mfs r12, rslr; \
|
||||
swi r12, r11, CTX_REG_OFFSET(SLR_REG);
|
||||
|
||||
#endif /*XPAR_MICROBLAZE_USE_STACK_PROTECTION */
|
||||
#define CTX_RESTORE_LR \
|
||||
CTX_RESTORE_REG(15);
|
||||
|
||||
/* Uses r11, stomps r12 */
|
||||
#define CTX_SAVE_MSR \
|
||||
mfs r12, rmsr; \
|
||||
swi r12, r11, CTX_REG_OFFSET(MSR);
|
||||
|
||||
/* Uses r11, stomps r12 */
|
||||
#define CTX_RESTORE_MSR \
|
||||
lwi r12, r11, CTX_REG_OFFSET(MSR); \
|
||||
mts rmsr, r12; \
|
||||
bri 4;
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
#define CTX_RESTORE_STACK_HIGH_REG \
|
||||
lwi r12, r11, CTX_REG_OFFSET(SHR_REG); \
|
||||
mts rshr, r12; \
|
||||
bri 4;
|
||||
|
||||
#define CTX_RESTORE_STACK_LOW_REG \
|
||||
lwi r12, r11, CTX_REG_OFFSET(SLR_REG); \
|
||||
mts rslr, r12; \
|
||||
bri 4;
|
||||
#endif /*XPAR_MICROBLAZE_USE_STACK_PROTECTION*/
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
|
||||
#define CTX_SAVE_STATE_REGS \
|
||||
CTX_SAVE_MSR; \
|
||||
CTX_SAVE_LR; \
|
||||
CTX_SAVE_SP; \
|
||||
CTX_SAVE_STACK_HIGH_REG; \
|
||||
CTX_SAVE_STACK_LOW_REG; \
|
||||
CTX_SAVE_REG(14); \
|
||||
CTX_SAVE_REG(16); \
|
||||
CTX_SAVE_REG(17); \
|
||||
CTX_SAVE_REG(18);
|
||||
|
||||
|
||||
#define CTX_RESTORE_STATE_REGS \
|
||||
CTX_RESTORE_MSR; \
|
||||
CTX_RESTORE_LR; \
|
||||
CTX_RESTORE_SP; \
|
||||
CTX_RESTORE_STACK_HIGH_REG; \
|
||||
CTX_RESTORE_STACK_LOW_REG; \
|
||||
CTX_RESTORE_REG(14); \
|
||||
CTX_RESTORE_REG(16); \
|
||||
CTX_RESTORE_REG(17); \
|
||||
CTX_RESTORE_REG(18);
|
||||
#else
|
||||
|
||||
#define CTX_SAVE_STATE_REGS \
|
||||
CTX_SAVE_MSR; \
|
||||
CTX_SAVE_LR; \
|
||||
CTX_SAVE_SP; \
|
||||
CTX_SAVE_REG(14); \
|
||||
CTX_SAVE_REG(16); \
|
||||
CTX_SAVE_REG(17); \
|
||||
CTX_SAVE_REG(18);
|
||||
|
||||
|
||||
#define CTX_RESTORE_STATE_REGS \
|
||||
CTX_RESTORE_MSR; \
|
||||
CTX_RESTORE_LR; \
|
||||
CTX_RESTORE_SP; \
|
||||
CTX_RESTORE_REG(14); \
|
||||
CTX_RESTORE_REG(16); \
|
||||
CTX_RESTORE_REG(17); \
|
||||
CTX_RESTORE_REG(18);
|
||||
#endif
|
||||
|
||||
|
||||
#define DISABLE_INTERRUPTS \
|
||||
mfs r11, rmsr; \
|
||||
andi r11, r11, ~2; \
|
||||
mts rmsr, r11; \
|
||||
bri 4;
|
||||
|
||||
#define ENABLE_INTERRUPTS \
|
||||
mfs r11, rmsr; \
|
||||
ori r11, r11, 2; \
|
||||
mts rmsr, r11; \
|
||||
bri 4;
|
||||
|
||||
|
||||
#define RESTORE_KERNEL_CONTEXT \
|
||||
lwi r2, r0, kernelr2; \
|
||||
lwi r13, r0, kernelr13;
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* System Call Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Syscall Macros */
|
||||
|
||||
#define SYSCALL_STACK_FRAME_SIZ (4*32)
|
||||
|
||||
#define SYSCALL_SAVE_TMP \
|
||||
PUSH_REG(11); \
|
||||
/* PUSH_REG(12); */
|
||||
|
||||
#define SYSCALL_RESTORE_TMP \
|
||||
POP_REG(11); \
|
||||
/* POP_REG(12); */
|
||||
|
||||
#define SYSCALL_SAVE_SDA_REGS \
|
||||
PUSH_REG(2); \
|
||||
PUSH_REG(13);
|
||||
|
||||
#define SYSCALL_RESTORE_SDA_REGS \
|
||||
POP_REG(2); \
|
||||
POP_REG(13);
|
||||
|
||||
#define SYSCALL_SAVE_LR \
|
||||
PUSH_REG(15); \
|
||||
|
||||
#define SYSCALL_RESTORE_LR \
|
||||
POP_REG(15); \
|
||||
|
||||
#define SYSCALL_SAVE_RET \
|
||||
PUSH_REG (3); \
|
||||
PUSH_REG (4); \
|
||||
|
||||
#define SYSCALL_RESTORE_RET \
|
||||
POP_REG (3); \
|
||||
POP_REG (4); \
|
||||
|
||||
#define MSR_VM_MASK 0x00002000
|
||||
#define MSR_VMS_MASK 0x00004000
|
||||
#define MSR_EIP_MASK 0x00000200
|
||||
#define MSR_EE_MASK 0x00000100
|
||||
#define MSR_INTR_MASK 0x00000002
|
||||
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
#define SYSCALL_MSR_SET_VM \
|
||||
mfs r11, rmsr; \
|
||||
ori r11, r11, (MSR_VM_MASK | MSR_VMS_MASK | MSR_EE_MASK); \
|
||||
mts rmsr, r11; \
|
||||
bri 4;
|
||||
|
||||
#define IRQ_MSR_SET_VM \
|
||||
mfs r11, rmsr; \
|
||||
ori r11, r11, (MSR_VM_MASK | MSR_VMS_MASK | MSR_EE_MASK); \
|
||||
mts rmsr, r11; \
|
||||
bri 4;
|
||||
|
||||
#define EXCEPTION_MSR_SET_VM \
|
||||
mfs r11, rmsr; \
|
||||
ori r11, r11, (MSR_VM_MASK | MSR_VMS_MASK | MSR_EE_MASK); \
|
||||
mts rmsr, r11; \
|
||||
bri 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SYSTEM CALL HANDLER
|
||||
* -------------------
|
||||
* - Disable interrupts
|
||||
* - Save volatiles and a few other important registers. Do not save non-volatiles, they are callee-saved
|
||||
* - Look up the address for the system call and vector there (system call number in r10)
|
||||
* - After handling system call, (and assuming we were not rescheduled in between), check to see if rescheduling is
|
||||
* required. If so, then call the scheduler and if context switch is required, save context and restore new context.
|
||||
*
|
||||
* FIXME
|
||||
* -----
|
||||
* - Need to save and restore SDA structures to support separate executable mode
|
||||
* - Stack frame does not stick to standard EABI frame conventions
|
||||
*
|
||||
* STACK FRAME STRUCTURE
|
||||
* ---------------------
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | r0 |
|
||||
* +-------------+
|
||||
* | . |
|
||||
* | . |
|
||||
* | . |
|
||||
* | . |
|
||||
* +-------------+ + 124
|
||||
* | r31 |
|
||||
* +-------------+ + 128
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*/
|
||||
|
||||
.global _exception_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.ent system_call_handler
|
||||
_exception_handler:
|
||||
system_call_handler:
|
||||
addik r1, r1, -SYSCALL_STACK_FRAME_SIZ;
|
||||
SYSCALL_SAVE_TMP;
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
/* MicroBlaze sets VM bit to 0 and sets VMS = 1 when executing syscall instruction (bralid r15, 0x8).
|
||||
We want VM mode enabled always. So we set it here again */
|
||||
SYSCALL_MSR_SET_VM;
|
||||
#endif
|
||||
lbui r11, r0, entry_mode; /* Do not disable interrupts if entry mode is ENTRY_MODE_KERNEL */
|
||||
bnei r11, handle_syscall;
|
||||
DISABLE_INTERRUPTS;
|
||||
handle_syscall:
|
||||
SYSCALL_SAVE_LR;
|
||||
/* SYSCALL_SAVE_SDA_REGS; */
|
||||
/* RESTORE_KERNEL_CONTEXT; */
|
||||
add r10, r10, r10; /* Load syscall addresss from syscall table */
|
||||
add r10, r10, r10; /* (4 * syscall number) */
|
||||
lwi r10, r10, syscall_table;
|
||||
brald r15, r10; /* Make the system call here */
|
||||
nop;
|
||||
lbui r11, r0, entry_mode;
|
||||
bnei r11, out_syscall;
|
||||
SYSCALL_SAVE_RET; /* Save return value of the system call to avoid stomping them in calls below */
|
||||
lbui r11, r0, resched;
|
||||
beqi r11, ret_syscall; /* No rescheduling. Lets get out of the system call */
|
||||
brlid r15, scheduler;
|
||||
nop;
|
||||
bnei r3, ret_syscall; /* Scheduler returns 1 => No rescheduling */
|
||||
GET_CTX_SAVE_PROC (r5);
|
||||
brlid r15, save_context; /* Call save_context with the pointer to the context structure in r5 */
|
||||
nop;
|
||||
swi r0, r0, ctx_save_process; /* Set the ctx_save_process identifier to NULL */
|
||||
beqi r3, restore_context; /* When I (who was saved in save_context above) am restored, I will have 1 in r3 */
|
||||
/* Otherwise a new process is to execute. So restore the new context */
|
||||
ret_syscall:
|
||||
brlid r15, proc_restore_state; /* Call C routine to restore application level state. Machine level state restored below */
|
||||
nop;
|
||||
SYSCALL_RESTORE_RET; /* Restore the return value of the system call */
|
||||
/* SYSCALL_RESTORE_SDA_REGS; */
|
||||
lbui r11, r0, entry_mode;
|
||||
bnei r11, out_syscall;
|
||||
ENABLE_INTERRUPTS;
|
||||
out_syscall:
|
||||
SYSCALL_RESTORE_TMP;
|
||||
SYSCALL_RESTORE_LR;
|
||||
rtsd r15, 8;
|
||||
addik r1, r1, SYSCALL_STACK_FRAME_SIZ;
|
||||
.end system_call_handler
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Interrupt Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* IRQ Macros */
|
||||
|
||||
#define IRQ_STACK_FRAME_SIZ (4*13)
|
||||
|
||||
#define IRQ_SAVE_TMP \
|
||||
PUSH_REG (11); \
|
||||
PUSH_REG (12);
|
||||
|
||||
#define IRQ_RESTORE_TMP \
|
||||
POP_REG (11); \
|
||||
POP_REG (12);
|
||||
|
||||
#define IRQ_SAVE_LR \
|
||||
PUSH_REG (15); \
|
||||
|
||||
#define IRQ_RESTORE_LR \
|
||||
POP_REG (15); \
|
||||
|
||||
#define IRQ_SAVE_RET \
|
||||
PUSH_REG (3); \
|
||||
PUSH_REG (4); \
|
||||
|
||||
#define IRQ_SAVE_PARAMS \
|
||||
PUSH_REG (5); \
|
||||
PUSH_REG (6); \
|
||||
PUSH_REG (7); \
|
||||
PUSH_REG (8); \
|
||||
PUSH_REG (9); \
|
||||
PUSH_REG (10);
|
||||
|
||||
#define IRQ_RESTORE_RET \
|
||||
POP_REG (3); \
|
||||
POP_REG (4); \
|
||||
|
||||
#define IRQ_RESTORE_PARAMS \
|
||||
POP_REG (5); \
|
||||
POP_REG (6); \
|
||||
POP_REG (7); \
|
||||
POP_REG (8); \
|
||||
POP_REG (9); \
|
||||
POP_REG (10);
|
||||
|
||||
/*
|
||||
* IRQ handler
|
||||
* - Save the complete context of the current task
|
||||
* - Switch to kernel interrupt stack
|
||||
* - Mark our current entry mode as ENTRY_KERNEL
|
||||
* - Invoke the main IRQ handler
|
||||
* - Restore context (and user stack)
|
||||
*/
|
||||
.global irq_entry
|
||||
.global _interrupt_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.ent irq_entry
|
||||
_interrupt_handler:
|
||||
irq_entry:
|
||||
addik r1, r1, -IRQ_STACK_FRAME_SIZ; /* Interrupts are turned off here */
|
||||
IRQ_SAVE_TMP;
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
/* MicroBlaze sets VM bit to 0 and sets VMS = 1 when interrupted.
|
||||
We want VM mode enabled always. So we set it here again */
|
||||
IRQ_MSR_SET_VM;
|
||||
#endif
|
||||
GET_CURRENT_PROC (r11); /* Get the context pointer into r11 */
|
||||
CTX_SAVE_STATE_REGS; /* Save MSR, SP, LR and other state regs (r14,r16,r17,r18) */
|
||||
CTX_SAVE_REG (2); /* Save complete context in process context structure */
|
||||
CTX_SAVE_REG (3);
|
||||
CTX_SAVE_REG (4);
|
||||
CTX_SAVE_REG (5);
|
||||
CTX_SAVE_REG (6);
|
||||
CTX_SAVE_REG (7);
|
||||
CTX_SAVE_REG (8);
|
||||
CTX_SAVE_REG (9);
|
||||
CTX_SAVE_REG (10);
|
||||
CTX_SAVE_REG (13);
|
||||
CTX_SAVE_REG (19);
|
||||
CTX_SAVE_REG (20);
|
||||
CTX_SAVE_REG (21);
|
||||
CTX_SAVE_REG (22);
|
||||
CTX_SAVE_REG (23);
|
||||
CTX_SAVE_REG (24);
|
||||
CTX_SAVE_REG (25);
|
||||
CTX_SAVE_REG (26);
|
||||
CTX_SAVE_REG (27);
|
||||
CTX_SAVE_REG (28);
|
||||
CTX_SAVE_REG (29);
|
||||
CTX_SAVE_REG (30);
|
||||
CTX_SAVE_REG (31);
|
||||
/* RESTORE_KERNEL_CONTEXT; */
|
||||
brlid r15, pit_disable; /* Stop the running PIT. CR 225388 -- For some reason, the scheme where */
|
||||
nop; /* the PIT is running free does not seem to work. i.e have to disable here */
|
||||
GET_CURRENT_PROC (r11); /* Get the context pointer into r11 */
|
||||
ori r5, r0, ISRFLAG_INTERRUPT;
|
||||
sbi r5, r11, ISRFLAG_OFFSET; /* Mark entry as from ISR */
|
||||
sbi r5, r0, entry_mode; /* Entry mode kernel */
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
lwi r12, r0, kernel_irq_stack_ptr;
|
||||
mts rshr, r12;
|
||||
lwi r12, r0, kernel_irq_stack_ptr_end;
|
||||
mts rslr, r12;
|
||||
#endif
|
||||
lwi r1, r0, kernel_irq_stack_ptr; /* Switch to kernel IRQ stack */
|
||||
#ifdef CONFIG_INTC
|
||||
brlid r15, XIntc_DeviceInterruptHandler; /* Handle the IRQ */
|
||||
ori r5, r0, SYSINTC_DEVICE_ID; /* Parameter to the interrupt handler */
|
||||
#else
|
||||
|
||||
brlid r15, timer_int_handler;
|
||||
nop; /* delay slot */
|
||||
#endif
|
||||
sbi r0, r0, entry_mode; /* Reset entry_mode flag */
|
||||
lbui r11, r0, resched;
|
||||
beqi r11, out_irq;
|
||||
brlid r15, scheduler;
|
||||
nop;
|
||||
swi r0, r0, ctx_save_process /* Reset the context save process identifier */
|
||||
out_irq:
|
||||
braid restore_context; /* End of IRQ handler. */
|
||||
nop; /* The context switch routine will take us where we need to go */
|
||||
.end irq_entry
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Context Save and Restore */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* Restore Context
|
||||
* - Doesn't care about any current state. Throws it all away
|
||||
* - Picks up the context from the context pointed to by current_process
|
||||
* - Refreshes PIT budget always
|
||||
* - Restores volatiles only if restoring from ISR context.
|
||||
*/
|
||||
|
||||
.global restore_context
|
||||
.section .text
|
||||
.align 2
|
||||
.ent restore_context
|
||||
restore_context:
|
||||
brlid r15, proc_restore_state; /* Call C routine to restore program level state. Machine level state restored below */
|
||||
nop;
|
||||
GET_CURRENT_PROC (r11);
|
||||
CTX_RESTORE_REG (2); /* Restore non-volatile registers */
|
||||
CTX_RESTORE_REG (13);
|
||||
CTX_RESTORE_REG (19);
|
||||
CTX_RESTORE_REG (20);
|
||||
CTX_RESTORE_REG (21);
|
||||
CTX_RESTORE_REG (22);
|
||||
CTX_RESTORE_REG (23);
|
||||
CTX_RESTORE_REG (24);
|
||||
CTX_RESTORE_REG (25);
|
||||
CTX_RESTORE_REG (26);
|
||||
CTX_RESTORE_REG (27);
|
||||
CTX_RESTORE_REG (28);
|
||||
CTX_RESTORE_REG (29);
|
||||
CTX_RESTORE_REG (30);
|
||||
CTX_RESTORE_REG (31);
|
||||
brlid r15, pit_reset; /* We do this as late as possible to give as much of the budget as possible to the new task */
|
||||
nop;
|
||||
GET_CURRENT_PROC (r11); /* Someone might have stomped it during the previous function call */
|
||||
CTX_RESTORE_STATE_REGS; /* Restore MSR, SP, LR and other state regs (r14,r16,r17,r18) */
|
||||
lbui r5, r11, ISRFLAG_OFFSET; /* If not entered the kernel through an ISR, restore only callee-saved and few other regs */
|
||||
xori r6, r5, ISRFLAG_SYSTEM_CALL;
|
||||
beqi r6, no_isr;
|
||||
|
||||
sbi r0, r11, ISRFLAG_OFFSET; /* Reset isrflag */
|
||||
xori r6, r5, ISRFLAG_NEW_PROC; /* Indicates interrupt */
|
||||
beqi r6, new_proc_restore;
|
||||
|
||||
/* Fall through to ISR */
|
||||
isr:
|
||||
CTX_RESTORE_REG (3); /* ISR restore: Restore volatile regs too */
|
||||
CTX_RESTORE_REG (4);
|
||||
CTX_RESTORE_REG (5);
|
||||
CTX_RESTORE_REG (6);
|
||||
CTX_RESTORE_REG (7);
|
||||
CTX_RESTORE_REG (8);
|
||||
CTX_RESTORE_REG (9);
|
||||
CTX_RESTORE_REG (10);
|
||||
IRQ_RESTORE_TMP;
|
||||
rtid r14, 0;
|
||||
addik r1, r1, IRQ_STACK_FRAME_SIZ; /* Restore the stack pointer here */
|
||||
new_proc_restore:
|
||||
rtid r14, 0;
|
||||
nop;
|
||||
no_isr:
|
||||
rtsd r15, 8; /* No need to restore r11. It is caller-saved */
|
||||
ori r3, r0, 1; /* Return 1 indicating return from restore context */
|
||||
.end restore_context
|
||||
|
||||
|
||||
/*
|
||||
* Save context
|
||||
* - Saves only kernel context
|
||||
* - Invoked only from "suspend". (ISR saves its own context)
|
||||
* - Indicate ISRFLAG 0
|
||||
* - Pointer to process structure in r5
|
||||
* - Needs to save lesser context than an ISR. Only Dedicated and non-volatile registers need to be saved.
|
||||
* - The current processes stack will be continued to use for a while till a restore is done.
|
||||
*/
|
||||
|
||||
.global save_context
|
||||
.section .text
|
||||
.align 2
|
||||
.ent save_context
|
||||
save_context:
|
||||
or r11, r0, r5; /* Move the process structure pointer to our work-horse r11 */
|
||||
CTX_SAVE_STATE_REGS; /* Save MSR, SP, LR and other state registers (r14,r16,r17,r18)*/
|
||||
CTX_SAVE_REG (2);
|
||||
CTX_SAVE_REG (13);
|
||||
CTX_SAVE_REG (19);
|
||||
CTX_SAVE_REG (20);
|
||||
CTX_SAVE_REG (21);
|
||||
CTX_SAVE_REG (22);
|
||||
CTX_SAVE_REG (23);
|
||||
CTX_SAVE_REG (24);
|
||||
CTX_SAVE_REG (25);
|
||||
CTX_SAVE_REG (26);
|
||||
CTX_SAVE_REG (27);
|
||||
CTX_SAVE_REG (28);
|
||||
CTX_SAVE_REG (29);
|
||||
CTX_SAVE_REG (30);
|
||||
CTX_SAVE_REG (31);
|
||||
sbi r0, r11, ISRFLAG_OFFSET; /* We will always be called from a system call */
|
||||
out_save_context:
|
||||
rtsd r15, 8;
|
||||
or r3, r0, r0; /* Return 0 */
|
||||
.end save_context
|
||||
|
||||
|
||||
#ifdef MICROBLAZE_EXCEPTIONS_ENABLED
|
||||
.global xilkernel_process_exception
|
||||
.global xilkernel_process_mmu_exception
|
||||
.section .text
|
||||
.align 2
|
||||
.ent xilkernel_process_exception
|
||||
xilkernel_process_exception:
|
||||
xilkernel_process_mmu_exception:
|
||||
lwi r1, r0, kernel_irq_stack_ptr; /* Switch to kernel IRQ stack */
|
||||
DISABLE_INTERRUPTS;
|
||||
|
||||
mfs r6, rear
|
||||
addik r7, r17, 0
|
||||
addik r17, r0, rted_loc
|
||||
rted_loc:
|
||||
rted r17, 8
|
||||
nop
|
||||
|
||||
brlid r15, microblaze_report_exception; /* Report the current exception back, if there is a way */
|
||||
nop; /* r5 contains ESR, r6 contains PC */
|
||||
|
||||
lbui r5, r0, current_pid /* Kill the current process */
|
||||
brlid r15, sys_kill
|
||||
nop
|
||||
|
||||
/* Control does not reach here. A context switch happens at the end of sys_kill */
|
||||
.end xilkernel_process_exception
|
||||
#endif
|
455
lib/bsp/xilkernel/src/src/arch/microblaze/hw_exception_handler.S
Executable file
455
lib/bsp/xilkernel/src/src/arch/microblaze/hw_exception_handler.S
Executable file
|
@ -0,0 +1,455 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Microblaze HW Exception Handler
|
||||
* - Non self-modifying exception handler for the following exception conditions
|
||||
* - Unalignment
|
||||
* - Instruction bus error
|
||||
* - Data bus error
|
||||
* - Illegal instruction opcode
|
||||
* - Divide-by-zero
|
||||
*/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "microblaze_exceptions_g.h"
|
||||
|
||||
/* Helpful Macros */
|
||||
#define EX_HANDLER_STACK_SIZ (4*19)
|
||||
#define RMSR_OFFSET 0
|
||||
#define REG_OFFSET(regnum) (4*regnum)
|
||||
#define NUM_TO_REG(num) r ## num
|
||||
|
||||
#define R3_TO_STACK(regnum) swi r3, r1, REG_OFFSET(regnum)
|
||||
#define R3_FROM_STACK(regnum) lwi r3, r1, REG_OFFSET(regnum)
|
||||
|
||||
#define PUSH_REG(regnum) swi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
|
||||
#define POP_REG(regnum) lwi NUM_TO_REG(regnum), r1, REG_OFFSET(regnum)
|
||||
|
||||
/* Uses r5 */
|
||||
#define PUSH_MSR \
|
||||
mfs r5, rmsr; \
|
||||
swi r5, r1, RMSR_OFFSET;
|
||||
|
||||
#define PUSH_MSR_AND_ENABLE_EXC \
|
||||
mfs r5, rmsr; \
|
||||
swi r5, r1, RMSR_OFFSET; \
|
||||
ori r5, r5, 0x100; /* Turn ON the EE bit*/ \
|
||||
mts rmsr, r5;
|
||||
|
||||
/* Uses r5 */
|
||||
#define POP_MSR \
|
||||
lwi r5, r1, RMSR_OFFSET; \
|
||||
mts rmsr, r5;
|
||||
|
||||
#define LWREG_NOP \
|
||||
bri ex_handler_unhandled; \
|
||||
nop;
|
||||
|
||||
#define SWREG_NOP \
|
||||
bri ex_handler_unhandled; \
|
||||
nop;
|
||||
|
||||
/* r3 is the source */
|
||||
#define R3_TO_LWREG_V(regnum) \
|
||||
R3_TO_STACK (regnum); \
|
||||
bri ex_handler_done;
|
||||
|
||||
/* r3 is the source */
|
||||
#define R3_TO_LWREG(regnum) \
|
||||
or NUM_TO_REG (regnum), r0, r3; \
|
||||
bri ex_handler_done;
|
||||
|
||||
/* r3 is the target */
|
||||
#define SWREG_TO_R3_V(regnum) \
|
||||
R3_FROM_STACK (regnum); \
|
||||
bri ex_sw_tail;
|
||||
|
||||
/* r3 is the target */
|
||||
#define SWREG_TO_R3(regnum) \
|
||||
or r3, r0, NUM_TO_REG (regnum); \
|
||||
bri ex_sw_tail;
|
||||
|
||||
/* regnum is the source */
|
||||
#define FP_EX_OPB_SAVE(regnum) \
|
||||
swi NUM_TO_REG (regnum), r0, mb_fpex_op_b; \
|
||||
nop; \
|
||||
bri handle_fp_ex_opa;
|
||||
|
||||
/* regnum is the source */
|
||||
#define FP_EX_OPB_SAVE_V(regnum) \
|
||||
R3_FROM_STACK (regnum); \
|
||||
swi r3, r0, mb_fpex_op_b; \
|
||||
bri handle_fp_ex_opa;
|
||||
|
||||
/* regnum is the source */
|
||||
#define FP_EX_OPA_SAVE(regnum) \
|
||||
swi NUM_TO_REG (regnum), r0, mb_fpex_op_a; \
|
||||
nop; \
|
||||
bri handle_fp_ex_done;
|
||||
|
||||
/* regnum is the source */
|
||||
#define FP_EX_OPA_SAVE_V(regnum) \
|
||||
R3_FROM_STACK (regnum); \
|
||||
swi r3, r0, mb_fpex_op_a; \
|
||||
bri handle_fp_ex_done;
|
||||
|
||||
#define FP_EX_UNHANDLED \
|
||||
bri fp_ex_unhandled; \
|
||||
nop; \
|
||||
nop;
|
||||
|
||||
/* ESR masks */
|
||||
#define ESR_EXC_MASK 0x0000001F
|
||||
#define ESR_REG_MASK 0x000003E0
|
||||
#define ESR_LW_SW_MASK 0x00000400
|
||||
#define ESR_WORD_MASK 0x00000800
|
||||
#define ESR_DS_MASK 0x00001000
|
||||
#define ESR_MMU_MASK 0x00000010
|
||||
|
||||
#ifdef MICROBLAZE_EXCEPTIONS_ENABLED /* If exceptions are enabled in the processor */
|
||||
|
||||
/*
|
||||
* hw_exception_handler - Handler for unaligned exceptions
|
||||
* Exception handler notes:
|
||||
* - Does not handle exceptions other than unaligned exceptions
|
||||
* - Does not handle exceptions during load into r17, r1, r0.
|
||||
* - Does not handle exceptions during store from r17 (cannot be done) and r1 (slows down common case)
|
||||
*
|
||||
* Relevant register structures
|
||||
*
|
||||
* EAR - |----|----|----|----|----|----|----|----|
|
||||
* - < ## 32 bit faulting address ## >
|
||||
*
|
||||
* ESR - |----|----|----|----|----| - | - |-----|-----|
|
||||
* - W S REG EXC
|
||||
*
|
||||
*
|
||||
* STACK FRAME STRUCTURE
|
||||
* ---------------------
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | MSR |
|
||||
* +-------------+ + 4
|
||||
* | r1 |
|
||||
* | . |
|
||||
* | . |
|
||||
* | . |
|
||||
* | . |
|
||||
* | r18 |
|
||||
* +-------------+ + 76
|
||||
* | . |
|
||||
* | . |
|
||||
*/
|
||||
|
||||
|
||||
.global _hw_exception_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.ent _hw_exception_handler
|
||||
_hw_exception_handler:
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
|
||||
/* Immediately halt for stack protection violation exception without using any stack */
|
||||
swi r3, r0, mb_sp_save_r3; /* Save temporary register */
|
||||
mfs r3, resr; /* Extract ESR[DS] */
|
||||
andi r3, r3, ESR_EXC_MASK;
|
||||
xori r3, r3, 0x7; /* Check for stack protection violation */
|
||||
bnei r3, ex_handler_not_sp_violation;
|
||||
ex_handler_sp_violation:
|
||||
bri 0; /* Halt here if stack protection violation */
|
||||
ex_handler_not_sp_violation:
|
||||
lwi r3, r0, mb_sp_save_r3; /* Restore temporary register */
|
||||
#endif /* defined(XPAR_MICROBLAZE_USE_STACK_PROTECTION) && (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1) */
|
||||
|
||||
addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
|
||||
PUSH_REG(3);
|
||||
PUSH_REG(4);
|
||||
PUSH_REG(5);
|
||||
PUSH_REG(6);
|
||||
#ifdef MICROBLAZE_CAN_HANDLE_EXCEPTIONS_IN_DELAY_SLOTS
|
||||
mfs r6, resr;
|
||||
andi r6, r6, ESR_DS_MASK;
|
||||
beqi r6, ex_handler_no_ds;
|
||||
mfs r17, rbtr;
|
||||
ex_handler_no_ds:
|
||||
#endif
|
||||
PUSH_REG(17);
|
||||
PUSH_MSR_AND_ENABLE_EXC; /* Exceptions enabled here. This will allow nested exceptions */
|
||||
|
||||
mfs r3, resr;
|
||||
andi r5, r3, ESR_EXC_MASK; /* Extract ESR[EXC] */
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
andi r6, r5, ESR_MMU_MASK; /* >= 0b10000 = MMU exception */
|
||||
bnei r6, xilkernel_process_mmu_exception; /* Jump to MMU exception handler*/
|
||||
#endif /* (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)) */
|
||||
|
||||
#ifdef XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS
|
||||
xori r6, r5, 1; /* 00001 = Unaligned Exception */
|
||||
beqi r6, handle_unaligned_ex ; /* Jump to unalignment exception handler*/
|
||||
#endif /* XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS */
|
||||
|
||||
handle_other_ex: /* Handle Other exceptions here */
|
||||
bri xilkernel_process_exception; /* Complete exception handling */
|
||||
|
||||
#ifdef XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS
|
||||
handle_unaligned_ex:
|
||||
andi r6, r3, ESR_REG_MASK; /* Mask and extract the register operand */
|
||||
srl r6, r6; /* r6 >> 5 */
|
||||
srl r6, r6;
|
||||
srl r6, r6;
|
||||
srl r6, r6;
|
||||
srl r6, r6;
|
||||
sbi r6, r0, ex_reg_op; /* Store the register operand in a temporary location */
|
||||
mfs r4, rear;
|
||||
andi r6, r3, ESR_LW_SW_MASK; /* Extract ESR[S] */
|
||||
bnei r6, ex_sw;
|
||||
ex_lw:
|
||||
andi r6, r3, ESR_WORD_MASK; /* Extract ESR[W] */
|
||||
beqi r6, ex_lhw;
|
||||
lbui r5, r4, 0; /* Exception address in r4 */
|
||||
sbi r5, r0, ex_tmp_data_loc_0; /* Load a word, byte-by-byte from destination address and save it in tmp space */
|
||||
lbui r5, r4, 1;
|
||||
sbi r5, r0, ex_tmp_data_loc_1;
|
||||
lbui r5, r4, 2;
|
||||
sbi r5, r0, ex_tmp_data_loc_2;
|
||||
lbui r5, r4, 3;
|
||||
sbi r5, r0, ex_tmp_data_loc_3;
|
||||
lwi r3, r0, ex_tmp_data_loc_0; /* Get the destination register value into r3 */
|
||||
bri ex_lw_tail;
|
||||
ex_lhw:
|
||||
lbui r5, r4, 0; /* Exception address in r4 */
|
||||
sbi r5, r0, ex_tmp_data_loc_0; /* Load a half-word, byte-by-byte from destination address and save it in tmp space */
|
||||
lbui r5, r4, 1;
|
||||
sbi r5, r0, ex_tmp_data_loc_1;
|
||||
lhui r3, r0, ex_tmp_data_loc_0; /* Get the destination register value into r3 */
|
||||
ex_lw_tail:
|
||||
lbui r5, r0, ex_reg_op; /* Get the destination register number into r5 */
|
||||
la r6, r0, lw_table; /* Form load_word jump table offset (lw_table + (8 * regnum)) */
|
||||
addk r5, r5, r5;
|
||||
addk r5, r5, r5;
|
||||
addk r5, r5, r5;
|
||||
addk r5, r5, r6;
|
||||
bra r5;
|
||||
ex_lw_end: /* Exception handling of load word, ends */
|
||||
ex_sw:
|
||||
lbui r5, r0, ex_reg_op; /* Get the destination register number into r5 */
|
||||
la r6, r0, sw_table; /* Form store_word jump table offset (sw_table + (8 * regnum)) */
|
||||
add r5, r5, r5;
|
||||
add r5, r5, r5;
|
||||
add r5, r5, r5;
|
||||
add r5, r5, r6;
|
||||
bra r5;
|
||||
ex_sw_tail:
|
||||
mfs r6, resr;
|
||||
andi r6, r6, ESR_WORD_MASK; /* Extract ESR[W] */
|
||||
beqi r6, ex_shw;
|
||||
swi r3, r0, ex_tmp_data_loc_0;
|
||||
lbui r3, r0, ex_tmp_data_loc_0; /* Store the word, byte-by-byte into destination address */
|
||||
sbi r3, r4, 0;
|
||||
lbui r3, r0, ex_tmp_data_loc_1;
|
||||
sbi r3, r4, 1;
|
||||
lbui r3, r0, ex_tmp_data_loc_2;
|
||||
sbi r3, r4, 2;
|
||||
lbui r3, r0, ex_tmp_data_loc_3;
|
||||
sbi r3, r4, 3;
|
||||
bri ex_handler_done;
|
||||
ex_shw:
|
||||
swi r3, r0, ex_tmp_data_loc_0; /* Store the lower half-word, byte-by-byte into destination address */
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lbui r3, r0, ex_tmp_data_loc_0;
|
||||
#else
|
||||
lbui r3, r0, ex_tmp_data_loc_2;
|
||||
#endif
|
||||
sbi r3, r4, 0;
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
lbui r3, r0, ex_tmp_data_loc_1;
|
||||
#else
|
||||
lbui r3, r0, ex_tmp_data_loc_3;
|
||||
#endif
|
||||
sbi r3, r4, 1;
|
||||
ex_sw_end: /* Exception handling of store word, ends. */
|
||||
bri ex_handler_done;
|
||||
#endif /* XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS */
|
||||
|
||||
ex_handler_done:
|
||||
POP_REG(17);
|
||||
POP_MSR;
|
||||
POP_REG(3);
|
||||
POP_REG(4);
|
||||
POP_REG(5);
|
||||
POP_REG(6);
|
||||
|
||||
rted r17, 0
|
||||
addik r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */
|
||||
ex_handler_unhandled:
|
||||
bri 0 /* UNHANDLED. TRAP HERE */
|
||||
.end _hw_exception_handler
|
||||
|
||||
#ifdef XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS
|
||||
|
||||
/*
|
||||
* hw_exception_handler Jump Table
|
||||
* - Contains code snippets for each register that caused the unaligned exception.
|
||||
* - Hence exception handler is NOT self-modifying
|
||||
* - Separate table for load exceptions and store exceptions.
|
||||
* - Each table is of size: (8 * 32) = 256 bytes
|
||||
*/
|
||||
|
||||
.section .text
|
||||
.align 4
|
||||
lw_table:
|
||||
lw_r0: R3_TO_LWREG (0);
|
||||
lw_r1: LWREG_NOP;
|
||||
lw_r2: R3_TO_LWREG (2);
|
||||
lw_r3: R3_TO_LWREG_V (3);
|
||||
lw_r4: R3_TO_LWREG_V (4);
|
||||
lw_r5: R3_TO_LWREG_V (5);
|
||||
lw_r6: R3_TO_LWREG_V (6);
|
||||
lw_r7: R3_TO_LWREG (7);
|
||||
lw_r8: R3_TO_LWREG (8);
|
||||
lw_r9: R3_TO_LWREG (9);
|
||||
lw_r10: R3_TO_LWREG (10);
|
||||
lw_r11: R3_TO_LWREG (11);
|
||||
lw_r12: R3_TO_LWREG (12);
|
||||
lw_r13: R3_TO_LWREG (13);
|
||||
lw_r14: R3_TO_LWREG (14);
|
||||
lw_r15: R3_TO_LWREG (15);
|
||||
lw_r16: R3_TO_LWREG (16);
|
||||
lw_r17: LWREG_NOP;
|
||||
lw_r18: R3_TO_LWREG (18);
|
||||
lw_r19: R3_TO_LWREG (19);
|
||||
lw_r20: R3_TO_LWREG (20);
|
||||
lw_r21: R3_TO_LWREG (21);
|
||||
lw_r22: R3_TO_LWREG (22);
|
||||
lw_r23: R3_TO_LWREG (23);
|
||||
lw_r24: R3_TO_LWREG (24);
|
||||
lw_r25: R3_TO_LWREG (25);
|
||||
lw_r26: R3_TO_LWREG (26);
|
||||
lw_r27: R3_TO_LWREG (27);
|
||||
lw_r28: R3_TO_LWREG (28);
|
||||
lw_r29: R3_TO_LWREG (29);
|
||||
lw_r30: R3_TO_LWREG (30);
|
||||
lw_r31: R3_TO_LWREG (31);
|
||||
|
||||
sw_table:
|
||||
sw_r0: SWREG_TO_R3 (0);
|
||||
sw_r1: SWREG_NOP;
|
||||
sw_r2: SWREG_TO_R3 (2);
|
||||
sw_r3: SWREG_TO_R3_V (3);
|
||||
sw_r4: SWREG_TO_R3_V (4);
|
||||
sw_r5: SWREG_TO_R3_V (5);
|
||||
sw_r6: SWREG_TO_R3_V (6);
|
||||
sw_r7: SWREG_TO_R3 (7);
|
||||
sw_r8: SWREG_TO_R3 (8);
|
||||
sw_r9: SWREG_TO_R3 (9);
|
||||
sw_r10: SWREG_TO_R3 (10);
|
||||
sw_r11: SWREG_TO_R3 (11);
|
||||
sw_r12: SWREG_TO_R3 (12);
|
||||
sw_r13: SWREG_TO_R3 (13);
|
||||
sw_r14: SWREG_TO_R3 (14);
|
||||
sw_r15: SWREG_TO_R3 (15);
|
||||
sw_r16: SWREG_TO_R3 (16);
|
||||
sw_r17: SWREG_NOP;
|
||||
sw_r18: SWREG_TO_R3 (18);
|
||||
sw_r19: SWREG_TO_R3 (19);
|
||||
sw_r20: SWREG_TO_R3 (20);
|
||||
sw_r21: SWREG_TO_R3 (21);
|
||||
sw_r22: SWREG_TO_R3 (22);
|
||||
sw_r23: SWREG_TO_R3 (23);
|
||||
sw_r24: SWREG_TO_R3 (24);
|
||||
sw_r25: SWREG_TO_R3 (25);
|
||||
sw_r26: SWREG_TO_R3 (26);
|
||||
sw_r27: SWREG_TO_R3 (27);
|
||||
sw_r28: SWREG_TO_R3 (28);
|
||||
sw_r29: SWREG_TO_R3 (29);
|
||||
sw_r30: SWREG_TO_R3 (30);
|
||||
sw_r31: SWREG_TO_R3 (31);
|
||||
|
||||
/* Temporary data structures used in the handler */
|
||||
.section .data
|
||||
.align 2
|
||||
ex_tmp_data_loc_0:
|
||||
.byte 0
|
||||
ex_tmp_data_loc_1:
|
||||
.byte 0
|
||||
ex_tmp_data_loc_2:
|
||||
.byte 0
|
||||
ex_tmp_data_loc_3:
|
||||
.byte 0
|
||||
ex_reg_op:
|
||||
.byte 0
|
||||
|
||||
#endif /* (XPAR_MICROBLAZE_UNALIGNED_EXCEPTIONS) */
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
/* This is where we store the register used to check which exception occurred */
|
||||
.section .data
|
||||
.align 2
|
||||
mb_sp_save_r3:
|
||||
.long 0
|
||||
#endif /* defined(XPAR_MICROBLAZE_USE_STACK_PROTECTION) && (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1) */
|
||||
|
||||
/* The exception vector table */
|
||||
.section .data
|
||||
.align 2
|
||||
.global MB_ExceptionVectorTable
|
||||
MB_ExceptionVectorTable:
|
||||
.long XNullHandler
|
||||
.long 0 /* -- FSL Exception -- */
|
||||
.long XNullHandler
|
||||
.long 1 /* -- Unaligned Access Exception -- */
|
||||
.long XNullHandler
|
||||
.long 2 /* -- Illegal Opcode Exception -- */
|
||||
.long XNullHandler
|
||||
.long 3 /* -- IOPB Exception -- */
|
||||
.long XNullHandler
|
||||
.long 4 /* -- DOPB Exception -- */
|
||||
.long XNullHandler
|
||||
.long 5 /* -- Div-by-0 Exception -- */
|
||||
.long XNullHandler
|
||||
.long 6 /* -- FPU Exception -- */
|
||||
.long XNullHandler
|
||||
.long 7 /* -- MMU Exceptions -- */
|
||||
|
||||
#else /* Dummy exception handler, in case exceptions are not present in the processor */
|
||||
|
||||
.global _hw_exception_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.ent _hw_exception_handler
|
||||
_hw_exception_handler:
|
||||
bri 0;
|
||||
.end _hw_exception_handler
|
||||
|
||||
#endif /* MICROBLAZE_EXCEPTIONS_ENABLED */
|
420
lib/bsp/xilkernel/src/src/arch/microblaze/mb-hw.c
Executable file
420
lib/bsp/xilkernel/src/src/arch/microblaze/mb-hw.c
Executable file
|
@ -0,0 +1,420 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mb-hw.c
|
||||
//! Microblaze hardware specific initialization
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/process.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <xil_types.h>
|
||||
#include <xstatus.h>
|
||||
#include <xparameters.h>
|
||||
#include <sys/decls.h>
|
||||
#include <microblaze_exceptions_g.h>
|
||||
#include <sys/init.h>
|
||||
#include <mb_interface.h>
|
||||
#include <sys/decls.h>
|
||||
|
||||
#ifdef CONFIG_TIMER_PIT
|
||||
#include <xtmrctr_l.h>
|
||||
#endif
|
||||
#ifdef CONFIG_INTC
|
||||
#include <xintc.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TIMER_COUNTER_0 0
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifdef CONFIG_INTC
|
||||
XIntc sys_intc;
|
||||
#endif
|
||||
|
||||
extern pid_t current_pid;
|
||||
extern char did_resched;
|
||||
extern char timer_need_refresh;
|
||||
extern unsigned char sched_partial_tick;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void int_system_init(void);
|
||||
void setup_initial_context (process_struct *pcb, pid_t parent, unsigned int start_addr, unsigned int stackaddr, unsigned int stacksize);
|
||||
void setup_usr_irq_context (pid_t pid);
|
||||
void restore_kernel_context (void);
|
||||
void init_idle_task (void);
|
||||
void pit_initialize(unsigned int interval);
|
||||
unsigned
|
||||
int pit_get_value(void);
|
||||
void pit_set_interval( unsigned int interval);
|
||||
void pit_reset(void);
|
||||
void pit_continue(void);
|
||||
void pit_disable (void);
|
||||
void pit_stop(void);
|
||||
void pit_handle_interrupt(void);
|
||||
void microblaze_report_exception (unsigned int esr, unsigned int ear, unsigned int pc);
|
||||
|
||||
extern void timer_int_handler(void *unused);
|
||||
extern int mpu_init (void);
|
||||
#ifdef CONFIG_INTC
|
||||
extern XIntc_Config XIntc_ConfigTable[];
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - hw_init
|
||||
//! @desc
|
||||
//! Microblaze hardware specific initialization
|
||||
//! - If an interrupt controller is present register interrupt controller handler
|
||||
//! as the main interrupt handler. Register timer with interrupt controller handler
|
||||
//! - Else, Register timer interrupt handler as the main interrupt handler
|
||||
//! - Configure PIT is timer is PIT.
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void hw_init(void)
|
||||
{
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
if (!mpu_init ()) {
|
||||
DBG_PRINT ("XMK: MPU Initialization failed. Kernel will run without memory protection.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
int_system_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIMER_PIT
|
||||
pit_initialize(SYSTMR_INTERVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - int_system_init
|
||||
//! @desc
|
||||
//! Initialize microblaze interrupt handling system in the prescence of an interrupt controller.
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void int_system_init (void)
|
||||
{
|
||||
XStatus status;
|
||||
status = XIntc_Initialize (&sys_intc, SYSINTC_DEVICE_ID);
|
||||
if (status != XST_SUCCESS) {
|
||||
DBG_PRINT ("XMK Error: XIntc_Initialize failed.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// IntC ISR should service all interrupts
|
||||
XIntc_SetIntrSvcOption (SYSINTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION);
|
||||
|
||||
// Register XMK timer interrupt handler to the timer interrupt
|
||||
status = XIntc_Connect (&sys_intc, SYSTMR_INTR_ID, timer_int_handler, NULL);
|
||||
if (status != XST_SUCCESS) {
|
||||
DBG_PRINT ("XMK Error: init_int_system: XIntc_Connect failed.\r\n");
|
||||
return;
|
||||
}
|
||||
// Enable timer interrupt
|
||||
XIntc_Enable (&sys_intc, SYSTMR_INTR_ID);
|
||||
|
||||
// Start the interrupt controller
|
||||
status = XIntc_Start (&sys_intc, XIN_REAL_MODE);
|
||||
if (status != XST_SUCCESS) {
|
||||
DBG_PRINT ("XMK Error: init_int_system: XIntc_Start failed.\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INTC */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xmk_enter_kernel
|
||||
//! @desc
|
||||
//! Lock kernel by turning off ALL system interrupts
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - Locks kernel against ALL interrupts.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
inline void xmk_enter_kernel (void)
|
||||
{
|
||||
microblaze_disable_interrupts();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xmk_leave_kernel
|
||||
//! @desc
|
||||
//! Unlock kernel by turning on system timer interrupts
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - Unlocks kernel with respect to ALL interrupts
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
inline void xmk_leave_kernel( void )
|
||||
{
|
||||
microblaze_enable_interrupts();
|
||||
}
|
||||
|
||||
/* //! Setup context for user-level interrupt handler */
|
||||
/* inline void setup_usr_irq_context (pid_t pid) */
|
||||
/* { */
|
||||
/* asm volatile ("or r2, r0, %0" : : "r" (ptable[pid].pcontext.regs[2])); */
|
||||
/* asm volatile ("or r13, r0, %0" : : "r" (ptable[pid].pcontext.regs[13])); */
|
||||
/* } */
|
||||
|
||||
/* //! Restore kernel context */
|
||||
/* inline void restore_kernel_context () */
|
||||
/* { */
|
||||
/* asm volatile ("or r2, r0, %0" : : "r" (ptable[0].pcontext.regs[2])); */
|
||||
/* asm volatile ("or r13, r0, %0" : : "r" (ptable[0].pcontext.regs[13])); */
|
||||
/* } */
|
||||
|
||||
|
||||
void setup_initial_context (process_struct *pcb, pid_t parent, unsigned int start_addr, unsigned int stackaddr, unsigned int stacksize)
|
||||
{
|
||||
pcb->pcontext.regs[1] = stackaddr;
|
||||
pcb->pcontext.regs[14] = start_addr;
|
||||
pcb->pcontext.regs[2] = ptable[parent].pcontext.regs[2];
|
||||
pcb->pcontext.regs[13] = ptable[parent].pcontext.regs[13];
|
||||
pcb->pcontext.regs[32] = (ptable[parent].pcontext.regs[32]) | 0x00000100; // Inherit MSR
|
||||
pcb->pcontext.isrflag = ISRFLAG_NEW_PROC;
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
pcb->pcontext.regs[33] = stackaddr;
|
||||
pcb->pcontext.regs[34] = stackaddr - stacksize;
|
||||
#else
|
||||
stacksize = 0; /* Dummy to remove compilation warning */
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
#define mtslr(v) ({ __asm__ __volatile__ ( \
|
||||
"mts\trslr,%0\n\tnop\n" :: "d" (v) \
|
||||
); \
|
||||
})
|
||||
|
||||
#define mtshr(v) ({ __asm__ __volatile__ ( \
|
||||
"mts\trshr,%0\n\tnop\n" :: "d" (v) \
|
||||
); \
|
||||
})
|
||||
|
||||
#define mfslr() ({ unsigned int _rval; \
|
||||
__asm__ __volatile__ ( \
|
||||
"mfs\t%0,rslr\n" : "=d"(_rval) \
|
||||
); \
|
||||
_rval; \
|
||||
})
|
||||
|
||||
#define mfshr() ({ unsigned int _rval; \
|
||||
__asm__ __volatile__ ( \
|
||||
"mfs\t%0,rshr\n" : "=d"(_rval) \
|
||||
); \
|
||||
_rval; \
|
||||
})
|
||||
#endif
|
||||
|
||||
void init_idle_task (void)
|
||||
{
|
||||
unsigned int msr;
|
||||
|
||||
idle_task_pid = proc_create (PRIO_LOWEST); // Idle task (PID 0).
|
||||
ptable[idle_task_pid].state = PROC_RUN; // Idle task assumed to be running as soon as the kernel starts
|
||||
ptable[idle_task_pid].pcontext.regs[1] = (unsigned int)kernel_sp;
|
||||
ptable[idle_task_pid].pcontext.regs[14] = (unsigned int)idle_task;
|
||||
asm volatile ("or %0, r0, r2" : "=r" (ptable[idle_task_pid].pcontext.regs[2]));
|
||||
asm volatile ("or %0, r0, r13" : "=r" (ptable[idle_task_pid].pcontext.regs[13]));
|
||||
asm volatile ("mfs %0, rmsr" : "=r" (msr));
|
||||
ptable[idle_task_pid].pcontext.regs[32] = msr;
|
||||
#if (XPAR_MICROBLAZE_USE_STACK_PROTECTION == 1)
|
||||
ptable[idle_task_pid].pcontext.regs[33] = (unsigned int)kernel_sp;
|
||||
ptable[idle_task_pid].pcontext.regs[34] = (unsigned int)(void*)((unsigned int)&_stack_end);
|
||||
mtshr((unsigned int)kernel_sp);
|
||||
mtslr((unsigned int)(void*)((unsigned int)&_stack_end));
|
||||
#endif
|
||||
SET_CURRENT_PROCESS (idle_task_pid);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TIMER_PIT
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_initialize
|
||||
//! @desc
|
||||
//! Initialize the PIT timer in the system
|
||||
//! @param
|
||||
//! - interval is the interval to interrupt the system at.
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_initialize (unsigned int interval)
|
||||
{
|
||||
|
||||
// Set the load register value. This is the number of cycles the timer counts before interrupting.
|
||||
// -2 because the actual number of cycles will be +2
|
||||
pit_set_interval (interval);
|
||||
|
||||
// Load the interval value from the load register and reset the interrupt occurred mask
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
XTC_CSR_INT_OCCURED_MASK | XTC_CSR_LOAD_MASK );
|
||||
|
||||
// Configure the timer for generate mode, auto-reload mode, down count, interrupts enabled.
|
||||
// Also, start the timer.
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK |
|
||||
XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_reset
|
||||
//! @desc
|
||||
//! Enable and start PIT timer with configured PIT interval loaded to the PIT counter
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_reset (void)
|
||||
{
|
||||
unsigned int control_reg;
|
||||
|
||||
// Obtain control register value from PIT device
|
||||
control_reg = XTmrCtr_GetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0);
|
||||
|
||||
// Refresh budget only if the timer ran out
|
||||
if (timer_need_refresh) {
|
||||
// Re-load the interval value from load register and reset the interrupt occurred mask
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
control_reg | XTC_CSR_LOAD_MASK | XTC_CSR_INT_OCCURED_MASK);
|
||||
|
||||
// Remove the load mask and also enable the timer
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
(control_reg & (~XTC_CSR_LOAD_MASK)) | XTC_CSR_ENABLE_TMR_MASK);
|
||||
|
||||
// Reset scheduler/timer state
|
||||
timer_need_refresh = 0;
|
||||
sched_partial_tick = 0;
|
||||
did_resched = 0;
|
||||
|
||||
} else {
|
||||
// FIXME!
|
||||
// - did_resched seems bogus. We will be here only if we do a resched
|
||||
// seems redundant. Leaving it in, because it is harmless if redundant
|
||||
if (did_resched) {
|
||||
did_resched = 0;
|
||||
sched_partial_tick = 1;
|
||||
}
|
||||
|
||||
// Enable the timer. No need to reset interrupt. That would have been covered by previous conditional
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
(control_reg | XTC_CSR_ENABLE_TMR_MASK));
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_set_interval
|
||||
//! @desc
|
||||
//! Set the count down value for the PIT device that is clocking Xilkernel. Also stores the
|
||||
//! interval value in a global pit_timer_interval. This stored value is unused currently, but
|
||||
//! in future can be used to do computations on clock budget for a process.
|
||||
//! @param
|
||||
//! - interval
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_set_interval (unsigned int interval)
|
||||
{
|
||||
XTmrCtr_WriteReg (SYSTMR_BASEADDR, TIMER_COUNTER_0,
|
||||
XTC_TLR_OFFSET, interval);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_disable
|
||||
//! @desc
|
||||
//! Disable the PIT device so that it can no longer run and interrupt the system.
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - Assumes timer was previously configured.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_disable (void)
|
||||
{
|
||||
unsigned int control_reg;
|
||||
|
||||
// Obtain control register value from PIT device
|
||||
control_reg = XTmrCtr_GetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0);
|
||||
|
||||
// Remove the enable mask and update the status register
|
||||
control_reg &= ~(XTC_CSR_ENABLE_TMR_MASK);
|
||||
XTmrCtr_SetControlStatusReg (SYSTMR_BASEADDR, TIMER_COUNTER_0, control_reg);
|
||||
}
|
||||
|
||||
#else
|
||||
void pit_reset () {}
|
||||
void pit_disable () {}
|
||||
|
||||
#endif /* CONFIG_TIMER_PIT */
|
||||
|
||||
|
||||
#ifdef MICROBLAZE_EXCEPTIONS_ENABLED
|
||||
void microblaze_report_exception (unsigned int esr, unsigned int ear, unsigned int pc)
|
||||
{
|
||||
xil_printf ("XMK: pid (%d) performed illegal operation @ PC (0x%x),\r\n\tfault code: (0x%x).\r\n\tfault address: (0x%x).\r\n", current_pid, pc, esr, ear);
|
||||
xil_printf ("XMK: Terminating (%d).\r\n", current_pid);
|
||||
esr = 0;
|
||||
ear = 0;
|
||||
pc = 0;
|
||||
}
|
||||
#endif
|
311
lib/bsp/xilkernel/src/src/arch/microblaze/mpu.c
Executable file
311
lib/bsp/xilkernel/src/src/arch/microblaze/mpu.c
Executable file
|
@ -0,0 +1,311 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mpu.c
|
||||
//! Microblaze MPU hardware specific initialization
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <xparameters.h>
|
||||
#include <mb_interface.h>
|
||||
#include <sys/mpu.h>
|
||||
#include <sys/decls.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE)
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#define TLBSIZE 64 /* Total number of available TLB entries */
|
||||
|
||||
#define MSR_VM_MASK 0x00002000
|
||||
#define MSR_VMS_MASK 0x00004000
|
||||
#define MSR_EE_MASK 0x00000100
|
||||
|
||||
static const unsigned int sizemask[8] = {
|
||||
0xfffffc00, 0xfffff000, 0xffffc000, 0xffff0000,
|
||||
0xfffc0000, 0xfff00000, 0xffc00000, 0xff000000
|
||||
};
|
||||
|
||||
static void tlb_add (int tlbindex, unsigned int tlbhi, unsigned int tlblo);
|
||||
static int tlb_add_entries (unsigned int base, unsigned int high, unsigned int tlbaccess);
|
||||
int mpu_init(void);
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
static struct {
|
||||
unsigned int tlbhi;
|
||||
unsigned int tlblo;
|
||||
} tlbentry[TLBSIZE];
|
||||
|
||||
extern xilkernel_io_range_t system_io_range[];
|
||||
extern int user_io_nranges __attribute__((weak));
|
||||
extern xilkernel_io_range_t user_io_range[] __attribute__((weak));
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - tlb_add
|
||||
//! @desc
|
||||
//! Add a single TLB entry
|
||||
//! @param
|
||||
//! - tlbindex is the index of the TLB entry to be updated
|
||||
//! - tlbhi is the value of the TLBHI field
|
||||
//! - tlblo is the value of the TLBLO field
|
||||
//! @return
|
||||
//! - none
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
static inline void tlb_add(int tlbindex, unsigned int tlbhi, unsigned int tlblo)
|
||||
{
|
||||
__asm__ __volatile__ ("mts rtlbx, %2 \n\t"
|
||||
"mts rtlbhi, %0 \n\t"
|
||||
"mts rtlblo, %1 \n\t"
|
||||
:: "r" (tlbhi),
|
||||
"r" (tlblo),
|
||||
"r" (tlbindex));
|
||||
|
||||
tlbentry[tlbindex].tlbhi = tlbhi;
|
||||
tlbentry[tlbindex].tlblo = tlblo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - mpu_init
|
||||
//! @desc
|
||||
//! Given a base and high address, figure out the minimum number page mappings/TLB entries required
|
||||
//! to cover the area. This function uses recursion to figure out the entire range of mappings.
|
||||
//! @param
|
||||
//! - base is the base address of the region of memory
|
||||
//! - high is the high address of the region of memory
|
||||
//! - tlbaccess is the type of access required for this region of memory. It can be
|
||||
//! a logical or-ing of the following flags.
|
||||
//! - 0 indicates read-only access
|
||||
//! - TLB_ACCESS_EXECUTABLE means the region is executable
|
||||
//! - TLB_ACCESS_WRITABLE means the region is writable
|
||||
//! @return
|
||||
//! - 1 on success and 0 on failure
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
static int tlb_add_entries (unsigned int base, unsigned int high, unsigned int tlbaccess)
|
||||
{
|
||||
int sizeindex, tlbsizemask;
|
||||
unsigned int tlbhi, tlblo;
|
||||
unsigned int area_base, area_high, area_size;
|
||||
static int tlbindex = 0;
|
||||
|
||||
// Align base and high to 1KB boundaries
|
||||
base = base & 0xfffffc00;
|
||||
high = (high >= 0xfffffc00) ? 0xffffffff : ((high + 0x400) & 0xfffffc00) - 1;
|
||||
|
||||
// Start trying to allocate pages from 16 MB granularity down to 1 KB
|
||||
area_size = 0x1000000; // 16 MB
|
||||
tlbsizemask = 0x380; // TLBHI[SIZE] = 7 (16 MB)
|
||||
|
||||
for (sizeindex = 7; sizeindex >= 0; sizeindex--) {
|
||||
area_base = base & sizemask[sizeindex];
|
||||
area_high = area_base + (area_size - 1);
|
||||
|
||||
// if (area_base <= (0xffffffff - (area_size - 1))) {
|
||||
|
||||
if ((area_base >= base) && (area_high <= high)) {
|
||||
|
||||
if (tlbindex < TLBSIZE) {
|
||||
tlbhi = (base & sizemask[sizeindex]) | tlbsizemask | 0x40; // TLBHI: TAG, SIZE, V
|
||||
tlblo = (base & sizemask[sizeindex]) | tlbaccess | 0x8; // TLBLO: RPN, EX, WR, W
|
||||
tlb_add (tlbindex, tlbhi, tlblo);
|
||||
|
||||
// DPRINTF ("XMK: TLB %d region: 0x%x - 0x%x, size: 0x%x, access: 0x%x.\r\n", tlbindex, base & sizemask[sizeindex],
|
||||
// (base & sizemask[sizeindex]) + area_size - 1,
|
||||
// tlbsizemask >> 7, tlbaccess >> 8);
|
||||
|
||||
tlbindex++;
|
||||
} else {
|
||||
// We only handle the 64 entry UTLB management for now
|
||||
DPRINTF ("XMK: Out of TLB entries.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recursively add entries for lower area
|
||||
if (area_base > base)
|
||||
if (!tlb_add_entries (base, area_base - 1, tlbaccess))
|
||||
return 0;
|
||||
|
||||
// Recursively add entries for higher area
|
||||
if (area_high < high)
|
||||
if (!tlb_add_entries(area_high + 1, high, tlbaccess))
|
||||
return 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// else, we try the next lower page size
|
||||
area_size = area_size >> 2;
|
||||
tlbsizemask = tlbsizemask - 0x80;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - mpu_init
|
||||
//! @desc
|
||||
//! Initialize and use MicroBlaze MPU/MMU features for providing memory protection.
|
||||
//1
|
||||
//! - This code assumes the following logical sections are present in the linker script,
|
||||
//! aligned at a 1K boundary and are clearly demarcated by the labels shown. If not,
|
||||
//! this function ignore the missing logical sections silently.
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION .vectors
|
||||
//! START_LABEL n.a
|
||||
//! END_LABEL n.a
|
||||
//! CONTAINS Executable vector sections. Do not need TLBs as MB always enters these
|
||||
//! in priv/unprotected mode.
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION .text
|
||||
//! START_LABEL _ftext
|
||||
//! END_LABEL _etext
|
||||
//! CONTAINS Executable instruction sections.
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION .data
|
||||
//! START_LABEL _fdata
|
||||
//! END_LABEL _edata
|
||||
//! CONTAINS Read-write data sections including small data sections.
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION .rodata
|
||||
//! START_LABEL _frodata
|
||||
//! END_LABEL _erodata
|
||||
//! CONTAINS Read only data sections including small data sections
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION .stack
|
||||
//! START_LABEL _stack_end
|
||||
//! END_LABEL _stack
|
||||
//! CONTAINS Kernel stack with 1 KB guard page above and below
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION stack guard page (top)
|
||||
//! START_LABEL _fstack_guard_top
|
||||
//! END_LABEL _estack_guard_top
|
||||
//! CONTAINS Top kernel stack guard page (1 KB)
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//! SECTION stack guard page (bottom)
|
||||
//! START_LABEL _fstack_guard_bottom
|
||||
//! END_LABEL _estack_guard_bottom
|
||||
//! CONTAINS Bottom kernel stack guard page (1 KB)
|
||||
//! ---------------------------------------------------------------------------------------
|
||||
//!
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - 1 on success and 0 on failure
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int mpu_init(void)
|
||||
{
|
||||
unsigned int msr;
|
||||
int i;
|
||||
|
||||
DPRINTF ("XMK: Initializing memory protection.\r\n");
|
||||
|
||||
// Invalidate all TLB entries first
|
||||
for (i = 0; i < TLBSIZE; i++)
|
||||
tlb_add (i, 0, 0);
|
||||
|
||||
// Add TLB entries for CODE
|
||||
if (&_ftext != 0 && &_etext != 0) {
|
||||
if (!tlb_add_entries ((unsigned int)&_ftext, (unsigned int)&_etext, MPU_PROT_EXEC))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add TLB entries for DATA
|
||||
if (&_fdata != 0 && &_edata != 0) {
|
||||
if (!tlb_add_entries ((unsigned int)&_fdata, (unsigned int)&_edata, MPU_PROT_READWRITE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add TLB entries for RODATA
|
||||
if (&_frodata != 0 && &_erodata != 0) {
|
||||
if (!tlb_add_entries ((unsigned int)&_frodata, (unsigned int)&_erodata, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add TLB entries for STACK
|
||||
if (&_stack_end != 0 && &__stack != 0) {
|
||||
if (!tlb_add_entries ((unsigned int)&_stack_end, (unsigned int)&__stack, MPU_PROT_READWRITE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add TLB entries for Vector Table
|
||||
if (!tlb_add_entries ((unsigned int)0x00000000, (unsigned int)0x0000004F, MPU_PROT_EXEC))
|
||||
return 0;
|
||||
|
||||
// Add TLB entries for System I/O ranges
|
||||
for (i = 0; i < XILKERNEL_IO_NRANGES; i++)
|
||||
if (!tlb_add_entries ((unsigned int)system_io_range[i].baseaddr, (unsigned int)system_io_range[i].highaddr, system_io_range[i].flags))
|
||||
return 0;
|
||||
|
||||
// Add TLB entries for User I/O ranges (if specified)
|
||||
if (user_io_nranges != 0) {
|
||||
for (i = 0; i < user_io_nranges; i++)
|
||||
if (!tlb_add_entries ((unsigned int)user_io_range[i].baseaddr, (unsigned int)user_io_range[i].highaddr, user_io_range[i].flags))
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize PID register
|
||||
asm volatile ("mts rpid, r0 \n\t"
|
||||
"bri 4\n\t");
|
||||
|
||||
// Initialize ZPR register
|
||||
asm volatile ("mts rzpr, r0 \n\t"
|
||||
"bri 4\n\t");
|
||||
|
||||
// Initialize VM mode
|
||||
asm volatile ("mfs %0, rmsr \n\t"
|
||||
"ori %0, %0, %1 \n\t;"
|
||||
"mts rmsr, %0 \n\t"
|
||||
"bri 4\n\t" : "=r"(msr) : "i" (MSR_VM_MASK | MSR_VMS_MASK | MSR_EE_MASK));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* (XPAR_MICROBLAZE_USE_MMU >= 2) && !defined (XILKERNEL_MB_MPU_DISABLE) */
|
104
lib/bsp/xilkernel/src/src/arch/microblaze/timer_intr_handler.c
Executable file
104
lib/bsp/xilkernel/src/src/arch/microblaze/timer_intr_handler.c
Executable file
|
@ -0,0 +1,104 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file timer_intr.c
|
||||
//! This module contains the timer interrupt handler routine and associated
|
||||
//! support routines for microblaze.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/process.h>
|
||||
#ifdef CONFIG_INTC
|
||||
#include <xintc.h>
|
||||
extern XIntc sys_intc;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
unsigned int budget_ticks;
|
||||
#endif
|
||||
|
||||
//void timer_int_handler(void* unused);
|
||||
void timer_int_handler(void);
|
||||
extern void soft_tmr_handler (void);
|
||||
extern signed char resched;
|
||||
extern process_struct *current_process;
|
||||
unsigned int kernel_ticks; //! Ticks since kernel startup
|
||||
char timer_need_refresh = 0; //! Do we need a reset?
|
||||
unsigned char sched_partial_tick;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - timer_int_handler
|
||||
//! @desc
|
||||
//! System timer interrupt handler
|
||||
//! - Do a rescheduling operation
|
||||
//! - If a context switch occurs within this routine,
|
||||
//! - When returning out of process_scheduler, process executing will return in the appropriate
|
||||
//! context when it was switched out on a previous flow through this execution path.
|
||||
//! - Reset PIT interval to start a full time slice (if PIT in the system) (if INTC not present)
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - May NOT return from this routine if a NEW process context is scheduled in the scheduler
|
||||
//! - A context switch does not occur within this routine if an INTC is present. The switch
|
||||
//! occurs at the end of the INTC ISR.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void timer_int_handler (void)
|
||||
{
|
||||
// Update global kernel ticks so far
|
||||
kernel_ticks++;
|
||||
#ifdef CONFIG_STATS
|
||||
current_process->active_ticks++;
|
||||
budget_ticks++;
|
||||
#endif
|
||||
#ifdef CONFIG_TIME
|
||||
soft_tmr_handler ();
|
||||
#endif
|
||||
|
||||
if (sched_partial_tick) {
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
// Avoid one more starvation case. On a partial schedule tick,
|
||||
// you want to give the next full time quantum to the thread
|
||||
// which was scheduled partially and not any thread that
|
||||
// timed out in soft_tmr_handler.
|
||||
// Note: We do this only for RR scheduling where we don't
|
||||
// want starvation.
|
||||
resched = 0;
|
||||
#endif
|
||||
sched_partial_tick = 0;
|
||||
} else {
|
||||
resched = 1;
|
||||
}
|
||||
|
||||
timer_need_refresh = 1;
|
||||
}
|
61
lib/bsp/xilkernel/src/src/arch/ppc/Makefile
Executable file
61
lib/bsp/xilkernel/src/src/arch/ppc/Makefile
Executable file
|
@ -0,0 +1,61 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for arch directory
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
include ../../../cpu.make
|
||||
|
||||
OBJS = entry${CPU_TYPE}.o timer_intr_handler.o ppc-hw.o debugmon.o
|
||||
INCLUDEDIR = ../../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -c -D__ASM__ $< -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~
|
95
lib/bsp/xilkernel/src/src/arch/ppc/debugmon.c
Executable file
95
lib/bsp/xilkernel/src/src/arch/ppc/debugmon.c
Executable file
|
@ -0,0 +1,95 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file debugmon.c
|
||||
//! Kernel inbuilt debug monitor routines for PPC405
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/init.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/stats.h>
|
||||
|
||||
#ifdef CONFIG_DEBUGMON
|
||||
|
||||
void debugmon_dump_proc_info (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
xmk_enter_kernel ();
|
||||
DBG_PRINT ("kernel_dump_proc_info ----> \r\n");
|
||||
for (i = 0; i<MAX_PROCESS_CONTEXTS; i++) {
|
||||
if (!ptable[i].is_allocated)
|
||||
continue;
|
||||
|
||||
DBG_PRINT ("=============================>\r\n");
|
||||
DBG_PRINT ("pid: ");
|
||||
putnum (ptable[i].pid);
|
||||
DBG_PRINT ("\r\nstate: ");
|
||||
putnum (ptable[i].state);
|
||||
DBG_PRINT ("\r\nisrflag: ");
|
||||
putnum (ptable[i].pcontext.isrflag);
|
||||
|
||||
for (j=0; j<44; j++) {
|
||||
DBG_PRINT ("\r\nregs[ ");
|
||||
putnum (j);
|
||||
DBG_PRINT ("]: ");
|
||||
putnum (ptable[i].pcontext.regs[j]);
|
||||
}
|
||||
DBG_PRINT ("\r\n=============================>\r\n\r\n");
|
||||
}
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
void debugmon_stack_check (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void debugmon_dump_sched_info (void)
|
||||
{
|
||||
|
||||
}
|
||||
#endif /* CONFIG_DEBUGMON */
|
653
lib/bsp/xilkernel/src/src/arch/ppc/entry405.S
Executable file
653
lib/bsp/xilkernel/src/src/arch/ppc/entry405.S
Executable file
|
@ -0,0 +1,653 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! entry.S - Represents all the entry and exit points into the kernel
|
||||
//! i.e - System calls, Interrupts and Traps
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
*/
|
||||
#include <sys/entry.h>
|
||||
#include <sys/arch.h>
|
||||
#include <xreg405.h>
|
||||
|
||||
.extern entry_mode
|
||||
.extern resched
|
||||
.extern ptable
|
||||
.extern current_process, ctx_save_process /* Pointers to corresponding process control blocks */
|
||||
.extern restore_kernel_context
|
||||
.extern timer_int_handler
|
||||
.extern pit_reset, pit_disable
|
||||
.extern kernel_irq_stack_ptr
|
||||
.extern proc_restore_state
|
||||
.extern syscall_table
|
||||
|
||||
#define NUM_TO_REG(num) r ## num
|
||||
|
||||
#define STACK_SAVE(reg, offset) \
|
||||
stw reg, offset(1);
|
||||
|
||||
#define STACK_RESTORE(reg, offset) \
|
||||
lwz reg, offset(1);
|
||||
|
||||
/* Uses r11 */
|
||||
#define DISABLE_INTERRUPTS \
|
||||
mfmsr 11; \
|
||||
rlwinm 11, 11, 0, 17, 15; /* Turn OFF EE bit */ \
|
||||
mtmsr 11;
|
||||
|
||||
/* Uses r11 */
|
||||
#define ENABLE_INTERRUPTS \
|
||||
mfmsr 11; \
|
||||
ori 11, 11, XREG_MSR_NON_CRITICAL_INTERRUPT_ENABLE; /* Turn ON EE bit */ \
|
||||
mtmsr 11;
|
||||
|
||||
|
||||
#define GET_CURRENT_PROC(reg) \
|
||||
lis reg, current_process@ha; /* Require 2 instructions to load 32-bit value */ \
|
||||
lwz reg, current_process@l(reg);
|
||||
|
||||
#define GET_CTX_SAVE_PROC(reg) \
|
||||
lis reg, ctx_save_process@ha; /* Require 2 instructions to load 32-bit value */ \
|
||||
lwz reg, ctx_save_process@l(reg);
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* System Call Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Syscall Macros */
|
||||
|
||||
#define SYSCALL_STACK_FRAME_SIZ (32)
|
||||
|
||||
#define SC_NEXT_LR_FIELD (4)
|
||||
#define SC_LR_FIELD (8)
|
||||
#define SC_PADDING_BEG (SC_LR_FIELD + 4) /* 4 bytes of padding */
|
||||
#define SC_PADDING_END (SC_PADDING_BEG + 4)
|
||||
#define SC_R3_FIELD (SC_PADDING_END)
|
||||
#define SC_R4_FIELD (SC_R3_FIELD + 4)
|
||||
#define SC_R11_FIELD (SC_R4_FIELD + 4)
|
||||
#define SC_R12_FIELD (SC_R11_FIELD + 4)
|
||||
|
||||
#define SC_OFFSET(reg) (SC_R ## reg ## _FIELD)
|
||||
|
||||
#define SYSCALL_SAVE_TMP \
|
||||
STACK_SAVE(11, SC_OFFSET(11)); \
|
||||
STACK_SAVE(12, SC_OFFSET(12));
|
||||
|
||||
#define SYSCALL_RESTORE_TMP \
|
||||
STACK_RESTORE(11, SC_OFFSET(11)); \
|
||||
STACK_RESTORE(12, SC_OFFSET(12));
|
||||
|
||||
#define SYSCALL_SAVE_LR \
|
||||
mflr 11; \
|
||||
STACK_SAVE(11, SC_LR_FIELD);
|
||||
|
||||
#define SYSCALL_RESTORE_LR \
|
||||
STACK_RESTORE(11, SC_LR_FIELD); \
|
||||
mtlr 11;
|
||||
|
||||
#define SYSCALL_SAVE_RET \
|
||||
STACK_SAVE(3, SC_OFFSET(3)); \
|
||||
STACK_SAVE(4, SC_OFFSET(4));
|
||||
|
||||
#define SYSCALL_RESTORE_RET \
|
||||
STACK_RESTORE(3, SC_OFFSET(3)); \
|
||||
STACK_RESTORE(4, SC_OFFSET(4));
|
||||
|
||||
/*
|
||||
* SYSTEM CALL HANDLER
|
||||
* -------------------
|
||||
* - Disable interrupts
|
||||
* - Save volatiles and a few other important registers. Do not save non-volatiles, they are callee-saved
|
||||
* - Look up the address for the system call and vector there (system call number in r8)
|
||||
* - After handling system call, (and assuming we were not rescheduled in between), check to see if rescheduling is
|
||||
* required. If so, then call the scheduler and if context switch is required, save context and restore new context.
|
||||
*
|
||||
* FIXME
|
||||
* -----
|
||||
* - Need to save and restore SDA structures to support separate executable mode
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | LR |
|
||||
* +-------------+ + 12
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (4 bytes here)
|
||||
* +-------------+ + 16
|
||||
* | r3 |
|
||||
* +-------------+ + 20
|
||||
* | r4 |
|
||||
* +-------------+ + 24
|
||||
* | r11 |
|
||||
* +-------------+ + 28
|
||||
* | r12 |
|
||||
* +-------------+ + 32
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*
|
||||
*/
|
||||
.global system_call_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.type system_call_handler@function
|
||||
system_call_handler:
|
||||
stwu 1, -SYSCALL_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */
|
||||
SYSCALL_SAVE_TMP;
|
||||
SYSCALL_SAVE_LR;
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq handle_syscall; /* Do not disable interrupts if entry mode is ENTRY_MODE_KERNEL */
|
||||
DISABLE_INTERRUPTS;
|
||||
handle_syscall:
|
||||
/* SYSCALL_SAVE_SDA_REGS; */
|
||||
/* RESTORE_KERNEL_CONTEXT; */
|
||||
add 8, 8, 8; /* Load syscall addresss from syscall table */
|
||||
add 8, 8, 8; /* (4 * syscall number) */
|
||||
addis 8, 8, syscall_table@ha;
|
||||
lwz 8, syscall_table@l(8);
|
||||
mtlr 8;
|
||||
blrl; /* Make the system call here */
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq out_syscall; /* Entered system call in kernel mode. Quit early */
|
||||
SYSCALL_SAVE_RET; /* Save return value of the system call to avoid stomping them in calls below */
|
||||
lis 11, resched@ha;
|
||||
lbz 11, resched@l(11);
|
||||
cmpwi 11, 1;
|
||||
bne ret_syscall; /* No rescheduling. Lets get out of the system call */
|
||||
bl scheduler;
|
||||
cmpwi 3, 1;
|
||||
beq ret_syscall; /* Scheduler returns 1 => No rescheduling */
|
||||
GET_CTX_SAVE_PROC (3);
|
||||
bl save_context; /* Call save_context with the pointer to the context structure in r5 */
|
||||
li 12, 0;
|
||||
lis 11, ctx_save_process@ha;
|
||||
stw 12, ctx_save_process@l(11);
|
||||
cmpwi 3, 0;
|
||||
beq restore_context; /* When "I" (who was saved in save_context above) am restored, I will have 1 in r3 */
|
||||
/* Otherwise, a new process is to execute here. So restore the new context */
|
||||
ret_syscall:
|
||||
bl proc_restore_state ; /* Call C routine to restore application level state. Machine level state restored below */
|
||||
/* SYSCALL_RESTORE_SDA_REGS; */
|
||||
SYSCALL_RESTORE_RET; /* Restore the return value of the system call */
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq out_syscall; /* Entered system call in kernel mode. Don't enable interrupts */
|
||||
ENABLE_INTERRUPTS;
|
||||
out_syscall:
|
||||
SYSCALL_RESTORE_LR;
|
||||
SYSCALL_RESTORE_TMP;
|
||||
addi 1, 1, SYSCALL_STACK_FRAME_SIZ;
|
||||
blr;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Interrupt Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* IRQ Macros */
|
||||
|
||||
#define IRQ_STACK_FRAME_SIZ (16)
|
||||
|
||||
#define IRQ_NEXT_LR_FIELD (4)
|
||||
#define IRQ_PADDING_END (IRQ_NEXT_LR_FIELD) /* 0 bytes of padding */
|
||||
#define IRQ_R3_FIELD (IRQ_PADDING_END + 4)
|
||||
#define IRQ_R11_FIELD (IRQ_R3_FIELD + 4)
|
||||
|
||||
#define IRQ_OFFSET(reg) (IRQ_R ## reg ## _FIELD)
|
||||
|
||||
#define BR 3 /* Context save base register */
|
||||
|
||||
#define IRQ_SAVE_TMP \
|
||||
STACK_SAVE(3, IRQ_OFFSET(3)); \
|
||||
STACK_SAVE(11, IRQ_OFFSET(11));
|
||||
|
||||
#define IRQ_RESTORE_TMP \
|
||||
STACK_RESTORE(3, IRQ_OFFSET(3)); \
|
||||
STACK_RESTORE(11, IRQ_OFFSET(11));
|
||||
|
||||
#define CTX_SAVE_MSR_IN_SYSCALL(tr) \
|
||||
mfmsr tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR) ;
|
||||
|
||||
#define CTX_RESTORE_MSR_IN_SYSCALL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR) ; \
|
||||
mtmsr tr;
|
||||
|
||||
|
||||
#define CTX_SAVE_MSR_PC_CRITICAL(tr) \
|
||||
mfsrr3 tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR); \
|
||||
mfsrr2 tr; \
|
||||
stw tr, CTX_PC_FIELD(BR);
|
||||
|
||||
#define CTX_SAVE_MSR_PC_NON_CRITICAL(tr) \
|
||||
mfsrr1 tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR); \
|
||||
mfsrr0 tr; \
|
||||
stw tr, CTX_PC_FIELD(BR);
|
||||
|
||||
#define CTX_RESTORE_MSR_PC_CRITICAL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR); \
|
||||
mtsrr3 tr; \
|
||||
lwz tr, CTX_PC_FIELD(BR); \
|
||||
mtsrr2 tr;
|
||||
|
||||
#define CTX_RESTORE_MSR_PC_NON_CRITICAL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR); \
|
||||
mtsrr1 tr; \
|
||||
lwz tr, CTX_PC_FIELD(BR); \
|
||||
mtsrr0 tr;
|
||||
|
||||
#define CTX_SAVE_MSR_PC(type, tr) \
|
||||
CTX_SAVE_MSR_PC_ ## type (tr);
|
||||
|
||||
#define CTX_RESTORE_MSR_PC(type, tr) \
|
||||
CTX_RESTORE_MSR_PC_ ## type (tr);
|
||||
|
||||
#define CTX_SAVE_STATE_REGS(tr) \
|
||||
mflr tr; \
|
||||
stw tr, CTX_LR_FIELD(BR); \
|
||||
mfctr tr; \
|
||||
stw tr, CTX_CTR_FIELD(BR); \
|
||||
mfxer tr; \
|
||||
stw tr, CTX_XER_FIELD(BR); \
|
||||
mfcr tr; \
|
||||
stw tr, CTX_CR_FIELD(BR);
|
||||
|
||||
|
||||
#define CTX_RESTORE_STATE_REGS(tr) \
|
||||
lwz tr, CTX_LR_FIELD(BR); \
|
||||
mtlr tr; \
|
||||
lwz tr, CTX_CTR_FIELD(BR); \
|
||||
mtctr tr; \
|
||||
lwz tr, CTX_XER_FIELD(BR); \
|
||||
mtxer tr; \
|
||||
lwz tr, CTX_CR_FIELD(BR); \
|
||||
mtcr tr;
|
||||
|
||||
#define CTX_SAVE_GPREGS(sr) \
|
||||
stmw sr, CTX_GPR_REG_FIELD(sr)(BR);
|
||||
|
||||
#define CTX_RESTORE_GPREGS(sr) \
|
||||
lmw sr, CTX_GPR_REG_FIELD(sr)(BR);
|
||||
|
||||
#define CTX_SAVE_REG(reg) \
|
||||
stw reg, CTX_GPR_REG_FIELD(reg)(BR);
|
||||
|
||||
#define CTX_RESTORE_REG(reg) \
|
||||
lwz reg, CTX_GPR_REG_FIELD(reg)(BR);
|
||||
|
||||
#define IRQ_RETURN_CRITICAL \
|
||||
rfci;
|
||||
|
||||
#define IRQ_RETURN_NON_CRITICAL \
|
||||
rfi;
|
||||
|
||||
#define EXCEPTION_ENTRY(type) \
|
||||
stwu 1, -IRQ_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */ \
|
||||
IRQ_SAVE_TMP; /* Free up some temporaries for our use here */ \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
CTX_SAVE_MSR_PC (type, 11); /* Save MSR and PC */ \
|
||||
CTX_SAVE_STATE_REGS (11); /* Save state regs; Use 12 as temporary */ \
|
||||
CTX_SAVE_REG (0); /* Save all gp registers (0 - 31) in context structure */\
|
||||
CTX_SAVE_REG (1); \
|
||||
CTX_SAVE_REG (2); \
|
||||
CTX_SAVE_GPREGS (4); \
|
||||
li 11, ISRFLAG_ ## type; \
|
||||
stb 11, ISRFLAG_OFFSET(BR);
|
||||
|
||||
#define EXCEPTION_EXIT(type) \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
li 11, 0; /* Reset ISR flag */ \
|
||||
stb 11, ISRFLAG_OFFSET(BR); \
|
||||
CTX_RESTORE_MSR_PC (type, 11); /* Restore MSR and PC */ \
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */ \
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */ \
|
||||
CTX_RESTORE_REG (1); \
|
||||
CTX_RESTORE_REG (2); \
|
||||
CTX_RESTORE_GPREGS (4); \
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */ \
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */ \
|
||||
IRQ_RETURN_ ## type; \
|
||||
|
||||
#define IRQ_ENTRY(type) \
|
||||
stwu 1, -IRQ_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */ \
|
||||
IRQ_SAVE_TMP; /* Free up some temporaries for our use here */ \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
CTX_SAVE_MSR_PC (type, 11); /* Save MSR and PC */ \
|
||||
CTX_SAVE_STATE_REGS (11); /* Save state regs; Use 12 as temporary */ \
|
||||
CTX_SAVE_REG (0); /* Save all gp registers (0 - 31) in context structure */\
|
||||
CTX_SAVE_REG (1); \
|
||||
CTX_SAVE_REG (2); \
|
||||
CTX_SAVE_GPREGS (4); \
|
||||
li 11, ISRFLAG_ ## type; /* Mark entry as from ISR */ \
|
||||
stb 11, ISRFLAG_OFFSET(BR); \
|
||||
li 11, 1; \
|
||||
lis 12, entry_mode@ha; /* Mark kernel entry mode */ \
|
||||
stb 11, entry_mode@l(12); \
|
||||
lis 10, kernel_irq_stack_ptr@ha; /* Switch stacks */ \
|
||||
lwz 1, kernel_irq_stack_ptr@l(10);
|
||||
|
||||
#define IRQ_EXIT(type) \
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */ \
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */ \
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */ \
|
||||
CTX_RESTORE_REG (1); \
|
||||
CTX_RESTORE_REG (2); \
|
||||
CTX_RESTORE_GPREGS (4); \
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */ \
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */ \
|
||||
IRQ_RETURN_ ## type;
|
||||
|
||||
|
||||
/*
|
||||
* Exception handler
|
||||
* - For CRITICAL and NON-CRITICAL exceptions that the kernel is unaware of.
|
||||
* - i.e Rescheduling within such exceptions will NOT be handled
|
||||
* - Save the complete context of the current task (in the current processes' context structure)
|
||||
* - Invoke the main exception handler
|
||||
* - Restore context and return
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (0 bytes here)
|
||||
* +-------------+ + 8
|
||||
* | r3 |
|
||||
* +-------------+ + 12
|
||||
* | r11 |
|
||||
* +-------------+ + 16
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*/
|
||||
|
||||
#define EXCEPTION_HANDLER(type, int_num, base) \
|
||||
VECTOR_LABEL(base); \
|
||||
EXCEPTION_ENTRY (type); \
|
||||
li 3, int_num; /* Load the interrupt ordinal in r3 */ \
|
||||
lis 9, XExc_VectorTable@ha; /* Load the base address of the vector table */ \
|
||||
la 9, XExc_VectorTable@l(9); \
|
||||
slwi 0, 3, 4; \
|
||||
add 9, 9, 0; \
|
||||
lwz 11, 0(9); \
|
||||
lwz 3, 4(9); \
|
||||
mtlr 11; \
|
||||
blrl; /* Handle the exception here */ \
|
||||
EXCEPTION_EXIT (type); /* Return from the exception here */
|
||||
|
||||
/*
|
||||
* IRQ handler
|
||||
* - ONLY for EXTERNAL EXCEPTIONS (EE), critical input interrupt and PIT exceptions.
|
||||
* - The kernel is aware of these exceptions.
|
||||
* - Save the complete context of the current task
|
||||
* - Switch to kernel interrupt stack
|
||||
* - Mark our current entry mode as ENTRY_KERNEL
|
||||
* - Invoke the main IRQ handler
|
||||
* - If rescheduling occurred within the kernel, invoke the scheduler
|
||||
* - Call context restore routine to restore the currently chosen context.
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (0 bytes here)
|
||||
* +-------------+ + 8
|
||||
* | r3 |
|
||||
* +-------------+ + 12
|
||||
* | r11 |
|
||||
* +-------------+ + 16
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*/
|
||||
|
||||
#define IRQ_HANDLER(type, int_num, base) \
|
||||
VECTOR_LABEL(base); \
|
||||
IRQ_ENTRY (type); \
|
||||
/* bl pit_disable; */ \
|
||||
/* GET_CURRENT_PROC (BR); */ \
|
||||
li 3, int_num; /* Load the interrupt ordinal in r3 */ \
|
||||
lis 9, XExc_VectorTable@ha; /* Load the base address of the vector table */ \
|
||||
la 9, XExc_VectorTable@l(9); \
|
||||
slwi 0, 3, 4; \
|
||||
add 9, 9, 0; \
|
||||
lwz 11, 0(9); \
|
||||
lwz 3, 4(9); \
|
||||
mtlr 11; \
|
||||
blrl; /* Handle the exception here */ \
|
||||
li 10, 0; /* Reset entry mode flag */ \
|
||||
lis 12, entry_mode@ha; \
|
||||
stb 10, entry_mode@l(12); \
|
||||
lis 12, resched@ha; /* Check the reschedule flag */ \
|
||||
lbz 12, resched@l(12); \
|
||||
cmpwi 12, 1; \
|
||||
bne out_irq_ ## base; \
|
||||
bl scheduler; \
|
||||
li 10, 0; \
|
||||
lis 12, ctx_save_process@ha; \
|
||||
stw 10, ctx_save_process@l(12); \
|
||||
out_irq_ ## base ##: \
|
||||
b restore_context;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Context Save and Restore */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Restore Context
|
||||
* - Doesn't care about any current state. Throws it all away
|
||||
* - Picks up the context from the context pointed to by current_process
|
||||
* - Refreshes PIT budget always
|
||||
* - Restores volatiles only if restoring from ISR context.
|
||||
*/
|
||||
.global restore_context
|
||||
.section .text
|
||||
.align 2
|
||||
.type restore_context@function
|
||||
restore_context:
|
||||
bl proc_restore_state;
|
||||
bl pit_reset;
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register */
|
||||
lbz 11, ISRFLAG_OFFSET(BR);
|
||||
li 12, 0;
|
||||
stb 12, ISRFLAG_OFFSET(BR); /* Clear ISR Flag */
|
||||
cmpwi 11, ISRFLAG_SYSTEM_CALL; /* This is a system call entry */
|
||||
beq syscall_restore;
|
||||
cmpwi 11, ISRFLAG_NEW_PROC; /* This is a new process entry */
|
||||
beq new_proc_restore;
|
||||
cmpwi 11, ISRFLAG_CRITICAL; /* This is an entry from a CRITICAL ISR */
|
||||
beq crit_isr_restore;
|
||||
non_crit_isr_restore: /* Else this is an entry from a non-critical ISR */
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */
|
||||
IRQ_RETURN_NON_CRITICAL;
|
||||
crit_isr_restore:
|
||||
CTX_RESTORE_MSR_PC (CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */
|
||||
IRQ_RETURN_CRITICAL;
|
||||
new_proc_restore: /* Else this is an exit out from a newly created process */
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RETURN_NON_CRITICAL;
|
||||
syscall_restore:
|
||||
CTX_RESTORE_MSR_IN_SYSCALL(11) ;
|
||||
CTX_RESTORE_STATE_REGS (11);
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (13);
|
||||
li 3, 1; /* Return 1 indicating return from restore context */
|
||||
blr;
|
||||
|
||||
/*
|
||||
* Save context
|
||||
* - Saves only kernel context
|
||||
* - Invoked only from "suspend" (ISR saves its own context)
|
||||
* - Indicate ISRFLAG 0
|
||||
* - Pointer to process structure in r3
|
||||
* - Needs to save lesser context than an ISR. Only Dedicated and non-volatile registers need to be saved.
|
||||
* - The current processes stack will be continued to use for a while till a restore is done.
|
||||
*/
|
||||
|
||||
.global save_context
|
||||
.section .text
|
||||
.align 2
|
||||
.type save_context@function
|
||||
save_context:
|
||||
CTX_SAVE_MSR_IN_SYSCALL(12) ;
|
||||
CTX_SAVE_STATE_REGS (12); /* Save state registers using 12 as temporary */
|
||||
CTX_SAVE_REG (1);
|
||||
CTX_SAVE_REG (2);
|
||||
CTX_SAVE_GPREGS (13);
|
||||
li 12, 0;
|
||||
stb 12, ISRFLAG_OFFSET(BR); /* Save context always invoked from a system call */
|
||||
out_save_context:
|
||||
li 3, 0; /* Save context returns zero */
|
||||
blr;
|
||||
|
||||
|
||||
#define VECTOR_LABEL(base) \
|
||||
.org _vectorbase + 0x ## base; \
|
||||
.global _vector ## base; \
|
||||
_vector ## base ##: ;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------
|
||||
*
|
||||
* Vector table.
|
||||
*
|
||||
* Define the vector table for all exceptions. The code for each
|
||||
* exception is assembled inline at each vector entry point. Most
|
||||
* PPC exceptions are 0x100 bytes apart, so there is 256 bytes of
|
||||
* code space to handle an exception. The current exception code
|
||||
* spans about 204 bytes, this code size fits.
|
||||
*
|
||||
* NOTE:
|
||||
*
|
||||
* Vectors 0x1000 (programmable interval timer) and 0x1010
|
||||
* (fixed interval timer) and vectors 0x1010 (fixed interval timer) and
|
||||
* 0x1020 (watchdog timer) are only 16 bytes apart and don't have enough
|
||||
* room for the exception handling code to fit between them. Fortunately,
|
||||
* there is a hole in the exception location sequence. Vectors 0x1300
|
||||
* through 0x1F00 are not used in the 405. So as a work-around, relocate
|
||||
* the exception code for vectors 0x1010 and 0x1020 (where there isn't space)
|
||||
* to the unused locations 0x1300 and 0x1400 (where there is room).
|
||||
* Locations 0x1010 and 0x1020 merely contain a branch to the proper
|
||||
* relocated exception code; which fits within the 16 bytes of space
|
||||
* of these "special" vector locations.
|
||||
*
|
||||
* If in the future this code is used for a different PPC processor,
|
||||
* this vector table may need to be changed.
|
||||
*
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.section ".vectors","ax"
|
||||
.global _vectorbase
|
||||
_vectorbase:
|
||||
|
||||
EXCEPTION_HANDLER (CRITICAL, 0, 0000) ; /* Vector 0x0000, Jump to zero. */
|
||||
EXCEPTION_HANDLER (CRITICAL, 1, 0100) ; /* Vector 0x0100, Critical interrupt. */
|
||||
EXCEPTION_HANDLER (CRITICAL, 2, 0200) ; /* Vector 0x0200, Machine Check interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 3, 0300) ; /* Vector 0x0300, Data Storage interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 4, 0400) ; /* Vector 0x0400, Instruction Storage interrupt. */
|
||||
IRQ_HANDLER (NON_CRITICAL, 5, 0500) ; /* Vector 0x0500, External interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 6, 0600) ; /* Vector 0x0600, Alignment interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 7, 0700) ; /* Vector 0x0700, Program Interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 8, 0800) ; /* Vector 0x0800, FPU Unavailable interrupt. */
|
||||
.org _vectorbase + 0x0C00
|
||||
b system_call_handler;
|
||||
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 10, 0F20) ; /* Vector 0x0F20, APU Available interrupt. */
|
||||
|
||||
.org _vectorbase + 0x1000 /* Vector 0x1000, PIT interrupt. */
|
||||
VECTOR_LABEL(1000); /* This vector need the workaround described above */
|
||||
b _vector1300;
|
||||
|
||||
.org _vectorbase + 0x1010 /* Vector 0x1010, FIT interrupt. */
|
||||
VECTOR_LABEL(1010); /* This vector need the workaround described above */
|
||||
b _vector1400;
|
||||
|
||||
EXCEPTION_HANDLER (CRITICAL, 13, 1020) ; /* Vector 0x1020, Watchdog Timer interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 14, 1100) ; /* Vector 0x1100, Data TLB Miss interrupt. */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 15,1200); /* Vector 0x1200, Instruction TLB Miss interrupt. */
|
||||
IRQ_HANDLER (NON_CRITICAL, 11, 1300) ; /* Real vector code 0x1000, PIT interrupt exception. Worksaround space span problem */
|
||||
EXCEPTION_HANDLER (NON_CRITICAL, 12, 1400) ; /* Real vector code 0x1010, FIT interrupt exception. Worksaround space span problem */
|
||||
EXCEPTION_HANDLER (CRITICAL, 16, 2000) ; /* Vector 0x2000, Debug interrupt. */
|
668
lib/bsp/xilkernel/src/src/arch/ppc/entry440.S
Executable file
668
lib/bsp/xilkernel/src/src/arch/ppc/entry440.S
Executable file
|
@ -0,0 +1,668 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! entry.S - Represents all the entry and exit points into the kernel
|
||||
//! i.e - System calls, Interrupts and Traps
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
*/
|
||||
#include <sys/entry.h>
|
||||
#include <sys/arch.h>
|
||||
#include <xreg440.h>
|
||||
|
||||
.extern entry_mode
|
||||
.extern resched
|
||||
.extern ptable
|
||||
.extern current_process, ctx_save_process /* Pointers to corresponding process control blocks */
|
||||
.extern restore_kernel_context
|
||||
.extern timer_int_handler
|
||||
.extern pit_reset, pit_disable
|
||||
.extern kernel_irq_stack_ptr
|
||||
.extern proc_restore_state
|
||||
.extern syscall_table
|
||||
|
||||
#define NUM_TO_REG(num) r ## num
|
||||
|
||||
#define STACK_SAVE(reg, offset) \
|
||||
stw reg, offset(1);
|
||||
|
||||
#define STACK_RESTORE(reg, offset) \
|
||||
lwz reg, offset(1);
|
||||
|
||||
/* Uses r11 */
|
||||
#define DISABLE_INTERRUPTS \
|
||||
mfmsr 11; \
|
||||
rlwinm 11, 11, 0, 17, 15; /* Turn OFF EE bit */ \
|
||||
mtmsr 11;
|
||||
|
||||
/* Uses r11 */
|
||||
#define ENABLE_INTERRUPTS \
|
||||
mfmsr 11; \
|
||||
ori 11, 11, XREG_MSR_NON_CRITICAL_INTERRUPT_ENABLE; /* Turn ON EE bit */ \
|
||||
mtmsr 11;
|
||||
|
||||
#define SWITCH_IS_DS \
|
||||
mfmsr 3; \
|
||||
ori 3, 3, 0x10; /* reset MSR[IS,DS] bits */ \
|
||||
mtmsr 3;
|
||||
|
||||
#define GET_CURRENT_PROC(reg) \
|
||||
lis reg, current_process@ha; /* Require 2 instructions to load 32-bit value */ \
|
||||
lwz reg, current_process@l(reg);
|
||||
|
||||
#define GET_CTX_SAVE_PROC(reg) \
|
||||
lis reg, ctx_save_process@ha; /* Require 2 instructions to load 32-bit value */ \
|
||||
lwz reg, ctx_save_process@l(reg);
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* System Call Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* Syscall Macros */
|
||||
|
||||
#define SYSCALL_STACK_FRAME_SIZ (32)
|
||||
|
||||
#define SC_NEXT_LR_FIELD (4)
|
||||
#define SC_LR_FIELD (8)
|
||||
#define SC_PADDING_BEG (SC_LR_FIELD + 4) /* 4 bytes of padding */
|
||||
#define SC_PADDING_END (SC_PADDING_BEG + 4)
|
||||
#define SC_R3_FIELD (SC_PADDING_END)
|
||||
#define SC_R4_FIELD (SC_R3_FIELD + 4)
|
||||
#define SC_R11_FIELD (SC_R4_FIELD + 4)
|
||||
#define SC_R12_FIELD (SC_R11_FIELD + 4)
|
||||
|
||||
#define SC_OFFSET(reg) (SC_R ## reg ## _FIELD)
|
||||
|
||||
#define SYSCALL_SAVE_TMP \
|
||||
STACK_SAVE(11, SC_OFFSET(11)); \
|
||||
STACK_SAVE(12, SC_OFFSET(12));
|
||||
|
||||
#define SYSCALL_RESTORE_TMP \
|
||||
STACK_RESTORE(11, SC_OFFSET(11)); \
|
||||
STACK_RESTORE(12, SC_OFFSET(12));
|
||||
|
||||
#define SYSCALL_SAVE_LR \
|
||||
mflr 11; \
|
||||
STACK_SAVE(11, SC_LR_FIELD);
|
||||
|
||||
#define SYSCALL_RESTORE_LR \
|
||||
STACK_RESTORE(11, SC_LR_FIELD); \
|
||||
mtlr 11;
|
||||
|
||||
#define SYSCALL_SAVE_RET \
|
||||
STACK_SAVE(3, SC_OFFSET(3)); \
|
||||
STACK_SAVE(4, SC_OFFSET(4));
|
||||
|
||||
#define SYSCALL_RESTORE_RET \
|
||||
STACK_RESTORE(3, SC_OFFSET(3)); \
|
||||
STACK_RESTORE(4, SC_OFFSET(4));
|
||||
|
||||
/*
|
||||
* SYSTEM CALL HANDLER
|
||||
* -------------------
|
||||
* - Disable interrupts
|
||||
* - Save volatiles and a few other important registers. Do not save non-volatiles, they are callee-saved
|
||||
* - Look up the address for the system call and vector there (system call number in r8)
|
||||
* - After handling system call, (and assuming we were not rescheduled in between), check to see if rescheduling is
|
||||
* required. If so, then call the scheduler and if context switch is required, save context and restore new context.
|
||||
*
|
||||
* FIXME
|
||||
* -----
|
||||
* - Need to save and restore SDA structures to support separate executable mode
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | LR |
|
||||
* +-------------+ + 12
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (4 bytes here)
|
||||
* +-------------+ + 16
|
||||
* | r3 |
|
||||
* +-------------+ + 20
|
||||
* | r4 |
|
||||
* +-------------+ + 24
|
||||
* | r11 |
|
||||
* +-------------+ + 28
|
||||
* | r12 |
|
||||
* +-------------+ + 32
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*
|
||||
*/
|
||||
.global system_call_handler
|
||||
.section .text
|
||||
.align 2
|
||||
.type system_call_handler@function
|
||||
system_call_handler:
|
||||
stwu 1, -SYSCALL_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */
|
||||
SYSCALL_SAVE_TMP;
|
||||
SYSCALL_SAVE_LR;
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq handle_syscall; /* Do not disable interrupts if entry mode is ENTRY_MODE_KERNEL */
|
||||
DISABLE_INTERRUPTS;
|
||||
handle_syscall:
|
||||
/* SYSCALL_SAVE_SDA_REGS; */
|
||||
/* RESTORE_KERNEL_CONTEXT; */
|
||||
add 8, 8, 8; /* Load syscall addresss from syscall table */
|
||||
add 8, 8, 8; /* (4 * syscall number) */
|
||||
addis 8, 8, syscall_table@ha;
|
||||
lwz 8, syscall_table@l(8);
|
||||
mtlr 8;
|
||||
blrl; /* Make the system call here */
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq out_syscall; /* Entered system call in kernel mode. Quit early */
|
||||
SYSCALL_SAVE_RET; /* Save return value of the system call to avoid stomping them in calls below */
|
||||
lis 11, resched@ha;
|
||||
lbz 11, resched@l(11);
|
||||
cmpwi 11, 1;
|
||||
bne ret_syscall; /* No rescheduling. Lets get out of the system call */
|
||||
bl scheduler;
|
||||
cmpwi 3, 1;
|
||||
beq ret_syscall; /* Scheduler returns 1 => No rescheduling */
|
||||
GET_CTX_SAVE_PROC (3);
|
||||
bl save_context; /* Call save_context with the pointer to the context structure in r5 */
|
||||
li 12, 0;
|
||||
lis 11, ctx_save_process@ha;
|
||||
stw 12, ctx_save_process@l(11);
|
||||
cmpwi 3, 0;
|
||||
beq restore_context; /* When "I" (who was saved in save_context above) am restored, I will have 1 in r3 */
|
||||
/* Otherwise, a new process is to execute here. So restore the new context */
|
||||
ret_syscall:
|
||||
bl proc_restore_state ; /* Call C routine to restore application level state. Machine level state restored below */
|
||||
/* SYSCALL_RESTORE_SDA_REGS; */
|
||||
SYSCALL_RESTORE_RET; /* Restore the return value of the system call */
|
||||
lis 11, entry_mode@ha;
|
||||
lbz 11, entry_mode@l(11);
|
||||
cmpwi 11, 1;
|
||||
beq out_syscall; /* Entered system call in kernel mode. Don't enable interrupts */
|
||||
ENABLE_INTERRUPTS;
|
||||
out_syscall:
|
||||
SYSCALL_RESTORE_LR;
|
||||
SYSCALL_RESTORE_TMP;
|
||||
addi 1, 1, SYSCALL_STACK_FRAME_SIZ;
|
||||
blr;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Interrupt Handling */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/* IRQ Macros */
|
||||
|
||||
#define IRQ_STACK_FRAME_SIZ (16)
|
||||
|
||||
#define IRQ_NEXT_LR_FIELD (4)
|
||||
#define IRQ_PADDING_END (IRQ_NEXT_LR_FIELD) /* 0 bytes of padding */
|
||||
#define IRQ_R3_FIELD (IRQ_PADDING_END + 4)
|
||||
#define IRQ_R11_FIELD (IRQ_R3_FIELD + 4)
|
||||
|
||||
#define IRQ_OFFSET(reg) (IRQ_R ## reg ## _FIELD)
|
||||
|
||||
#define BR 3 /* Context save base register */
|
||||
|
||||
#define IRQ_SAVE_TMP \
|
||||
STACK_SAVE(11, IRQ_OFFSET(11)); \
|
||||
mfspr 11, XREG_SPR_SPRG0_SU; /* r3 gets saved into sprg0 in ivor */\
|
||||
STACK_SAVE(11, IRQ_OFFSET(3));
|
||||
|
||||
#define IRQ_RESTORE_TMP \
|
||||
STACK_RESTORE(3, IRQ_OFFSET(3)); \
|
||||
STACK_RESTORE(11, IRQ_OFFSET(11));
|
||||
|
||||
#define CTX_SAVE_MSR_IN_SYSCALL(tr) \
|
||||
mfmsr tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR) ;
|
||||
|
||||
#define CTX_RESTORE_MSR_IN_SYSCALL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR) ; \
|
||||
mtmsr tr;
|
||||
|
||||
|
||||
#define CTX_SAVE_MSR_PC_CRITICAL(tr) \
|
||||
mfcsrr1 tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR); \
|
||||
mfcsrr0 tr; \
|
||||
stw tr, CTX_PC_FIELD(BR);
|
||||
|
||||
#define CTX_SAVE_MSR_PC_NON_CRITICAL(tr) \
|
||||
mfsrr1 tr; \
|
||||
stw tr, CTX_MSR_FIELD(BR); \
|
||||
mfsrr0 tr; \
|
||||
stw tr, CTX_PC_FIELD(BR);
|
||||
|
||||
#define CTX_RESTORE_MSR_PC_CRITICAL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR); \
|
||||
mtcsrr1 tr; \
|
||||
lwz tr, CTX_PC_FIELD(BR); \
|
||||
mtcsrr0 tr;
|
||||
|
||||
#define CTX_RESTORE_MSR_PC_NON_CRITICAL(tr) \
|
||||
lwz tr, CTX_MSR_FIELD(BR); \
|
||||
mtsrr1 tr; \
|
||||
lwz tr, CTX_PC_FIELD(BR); \
|
||||
mtsrr0 tr;
|
||||
|
||||
#define CTX_SAVE_MSR_PC(type, tr) \
|
||||
CTX_SAVE_MSR_PC_ ## type (tr);
|
||||
|
||||
#define CTX_RESTORE_MSR_PC(type, tr) \
|
||||
CTX_RESTORE_MSR_PC_ ## type (tr);
|
||||
|
||||
#define CTX_SAVE_STATE_REGS(tr) \
|
||||
mflr tr; \
|
||||
stw tr, CTX_LR_FIELD(BR); \
|
||||
mfctr tr; \
|
||||
stw tr, CTX_CTR_FIELD(BR); \
|
||||
mfxer tr; \
|
||||
stw tr, CTX_XER_FIELD(BR); \
|
||||
mfcr tr; \
|
||||
stw tr, CTX_CR_FIELD(BR);
|
||||
|
||||
|
||||
#define CTX_RESTORE_STATE_REGS(tr) \
|
||||
lwz tr, CTX_LR_FIELD(BR); \
|
||||
mtlr tr; \
|
||||
lwz tr, CTX_CTR_FIELD(BR); \
|
||||
mtctr tr; \
|
||||
lwz tr, CTX_XER_FIELD(BR); \
|
||||
mtxer tr; \
|
||||
lwz tr, CTX_CR_FIELD(BR); \
|
||||
mtcr tr;
|
||||
|
||||
#define CTX_SAVE_GPREGS(sr) \
|
||||
stmw sr, CTX_GPR_REG_FIELD(sr)(BR);
|
||||
|
||||
#define CTX_RESTORE_GPREGS(sr) \
|
||||
lmw sr, CTX_GPR_REG_FIELD(sr)(BR);
|
||||
|
||||
#define CTX_SAVE_REG(reg) \
|
||||
stw reg, CTX_GPR_REG_FIELD(reg)(BR);
|
||||
|
||||
#define CTX_RESTORE_REG(reg) \
|
||||
lwz reg, CTX_GPR_REG_FIELD(reg)(BR);
|
||||
|
||||
#define IRQ_RETURN_CRITICAL \
|
||||
rfci;
|
||||
|
||||
#define IRQ_RETURN_NON_CRITICAL \
|
||||
rfi;
|
||||
|
||||
#define EXCEPTION_ENTRY(type) \
|
||||
SWITCH_IS_DS; \
|
||||
stwu 1, -IRQ_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */ \
|
||||
IRQ_SAVE_TMP; /* Free up some temporaries for our use here */ \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
CTX_SAVE_MSR_PC (type, 11); /* Save MSR and PC */ \
|
||||
CTX_SAVE_STATE_REGS (11); /* Save state regs; Use 12 as temporary */ \
|
||||
CTX_SAVE_REG (0); /* Save all gp registers (0 - 31) in context structure */\
|
||||
CTX_SAVE_REG (1); \
|
||||
CTX_SAVE_REG (2); \
|
||||
CTX_SAVE_GPREGS (4); \
|
||||
li 11, ISRFLAG_ ## type; \
|
||||
stb 11, ISRFLAG_OFFSET(BR);
|
||||
|
||||
#define EXCEPTION_EXIT(type) \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
li 11, 0; /* Reset ISR flag */ \
|
||||
stb 11, ISRFLAG_OFFSET(BR); \
|
||||
CTX_RESTORE_MSR_PC (type, 11); /* Restore MSR and PC */ \
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */ \
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */ \
|
||||
CTX_RESTORE_REG (1); \
|
||||
CTX_RESTORE_REG (2); \
|
||||
CTX_RESTORE_GPREGS (4); \
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */ \
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */ \
|
||||
IRQ_RETURN_ ## type; \
|
||||
|
||||
#define IRQ_ENTRY(type) \
|
||||
SWITCH_IS_DS; \
|
||||
stwu 1, -IRQ_STACK_FRAME_SIZ(1); /* Make space on the stack and save backchain */ \
|
||||
IRQ_SAVE_TMP; /* Free up some temporaries for our use here */ \
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register*/ \
|
||||
CTX_SAVE_MSR_PC (type, 11); /* Save MSR and PC */ \
|
||||
CTX_SAVE_STATE_REGS (11); /* Save state regs; Use 12 as temporary */ \
|
||||
CTX_SAVE_REG (0); /* Save all gp registers (0 - 31) in context structure */\
|
||||
CTX_SAVE_REG (1); \
|
||||
CTX_SAVE_REG (2); \
|
||||
CTX_SAVE_GPREGS (4); \
|
||||
li 11, ISRFLAG_ ## type; /* Mark entry as from ISR */ \
|
||||
stb 11, ISRFLAG_OFFSET(BR); \
|
||||
li 11, 1; \
|
||||
lis 12, entry_mode@ha; /* Mark kernel entry mode */ \
|
||||
stb 11, entry_mode@l(12); \
|
||||
lis 10, kernel_irq_stack_ptr@ha; /* Switch stacks */ \
|
||||
lwz 1, kernel_irq_stack_ptr@l(10);
|
||||
|
||||
#define IRQ_EXIT(type) \
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */ \
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */ \
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */ \
|
||||
CTX_RESTORE_REG (1); \
|
||||
CTX_RESTORE_REG (2); \
|
||||
CTX_RESTORE_GPREGS (4); \
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */ \
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */ \
|
||||
IRQ_RETURN_ ## type;
|
||||
|
||||
|
||||
/*
|
||||
* Exception handler
|
||||
* - For CRITICAL and NON-CRITICAL exceptions that the kernel is unaware of.
|
||||
* - i.e Rescheduling within such exceptions will NOT be handled
|
||||
* - Save the complete context of the current task (in the current processes' context structure)
|
||||
* - Invoke the main exception handler
|
||||
* - Restore context and return
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (0 bytes here)
|
||||
* +-------------+ + 8
|
||||
* | r3 |
|
||||
* +-------------+ + 12
|
||||
* | r11 |
|
||||
* +-------------+ + 16
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*/
|
||||
|
||||
#define EXCEPTION_HANDLER(type) \
|
||||
EXCEPTION_ENTRY (type); \
|
||||
mfspr 3, XREG_SPR_USPRG0; /* Get the interrupt ordinal in r3 */ \
|
||||
lis 9, XExc_VectorTable@ha; /* Load the base address of the vector table */ \
|
||||
la 9, XExc_VectorTable@l(9); \
|
||||
slwi 0, 3, 4; \
|
||||
add 9, 9, 0; \
|
||||
lwz 11, 0(9); \
|
||||
lwz 3, 4(9); \
|
||||
mtlr 11; \
|
||||
blrl; /* Handle the exception here */ \
|
||||
EXCEPTION_EXIT (type); /* Return from the exception here */
|
||||
|
||||
/*
|
||||
* IRQ handler
|
||||
* - ONLY for EXTERNAL EXCEPTIONS (EE), critical input interrupt and PIT exceptions.
|
||||
* - The kernel is aware of these exceptions.
|
||||
* - Save the complete context of the current task
|
||||
* - Switch to kernel interrupt stack
|
||||
* - Mark our current entry mode as ENTRY_KERNEL
|
||||
* - Invoke the main IRQ handler
|
||||
* - If rescheduling occurred within the kernel, invoke the scheduler
|
||||
* - Call context restore routine to restore the currently chosen context.
|
||||
*
|
||||
* STACK FRAME STRUCTURE (stack grows upwards in the figure below)
|
||||
* ---------------------
|
||||
*
|
||||
* - Sticks to standard EABI frame conventions
|
||||
* - Will work from a debugger
|
||||
*
|
||||
* +-------------+ + 0
|
||||
* | Back Chain |
|
||||
* +-------------+ + 4
|
||||
* | Next LR |
|
||||
* +-------------+ + 8
|
||||
* | Padding | Padding adjusts size to multiple of 8-bytes (0 bytes here)
|
||||
* +-------------+ + 8
|
||||
* | r3 |
|
||||
* +-------------+ + 12
|
||||
* | r11 |
|
||||
* +-------------+ + 16
|
||||
* | . |
|
||||
* | . |
|
||||
*
|
||||
*/
|
||||
|
||||
#define IRQ_HANDLER(type) \
|
||||
IRQ_ENTRY (type); \
|
||||
/* bl pit_disable; */ \
|
||||
/* GET_CURRENT_PROC (BR); */ \
|
||||
mfspr 3, XREG_SPR_USPRG0; /* Get the interrupt ordinal in r3 */ \
|
||||
lis 9, XExc_VectorTable@ha; /* Load the base address of the vector table */ \
|
||||
la 9, XExc_VectorTable@l(9); \
|
||||
slwi 0, 3, 4; \
|
||||
add 9, 9, 0; \
|
||||
lwz 11, 0(9); \
|
||||
lwz 3, 4(9); \
|
||||
mtlr 11; \
|
||||
blrl; /* Handle the exception here */ \
|
||||
li 10, 0; /* Reset entry mode flag */ \
|
||||
lis 12, entry_mode@ha; \
|
||||
stb 10, entry_mode@l(12); \
|
||||
lis 12, resched@ha; /* Check the reschedule flag */ \
|
||||
lbz 12, resched@l(12); \
|
||||
cmpwi 12, 1; \
|
||||
bne out_irq; \
|
||||
bl scheduler; \
|
||||
li 10, 0; \
|
||||
lis 12, ctx_save_process@ha; \
|
||||
stw 10, ctx_save_process@l(12); \
|
||||
out_irq: \
|
||||
b restore_context;
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
/* Context Save and Restore */
|
||||
/*--------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Restore Context
|
||||
* - Doesn't care about any current state. Throws it all away
|
||||
* - Picks up the context from the context pointed to by current_process
|
||||
* - Refreshes PIT budget always
|
||||
* - Restores volatiles only if restoring from ISR context.
|
||||
*/
|
||||
.global restore_context
|
||||
.section .text
|
||||
.align 2
|
||||
.type restore_context@function
|
||||
restore_context:
|
||||
bl proc_restore_state;
|
||||
bl pit_reset;
|
||||
GET_CURRENT_PROC (BR); /* Get the ctx ptr into ctx save base register */
|
||||
lbz 11, ISRFLAG_OFFSET(BR);
|
||||
li 12, 0;
|
||||
stb 12, ISRFLAG_OFFSET(BR); /* Clear ISR Flag */
|
||||
cmpwi 11, ISRFLAG_SYSTEM_CALL; /* This is a system call entry */
|
||||
beq syscall_restore;
|
||||
cmpwi 11, ISRFLAG_NEW_PROC; /* This is a new process entry */
|
||||
beq new_proc_restore;
|
||||
cmpwi 11, ISRFLAG_CRITICAL; /* This is an entry from a CRITICAL ISR */
|
||||
beq crit_isr_restore;
|
||||
non_crit_isr_restore: /* Else this is an entry from a non-critical ISR */
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */
|
||||
IRQ_RETURN_NON_CRITICAL;
|
||||
crit_isr_restore:
|
||||
CTX_RESTORE_MSR_PC (CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RESTORE_TMP; /* Restore temporaries here */
|
||||
addi 1, 1, IRQ_STACK_FRAME_SIZ; /* Free up stack space */
|
||||
IRQ_RETURN_CRITICAL;
|
||||
new_proc_restore: /* Else this is an exit out from a newly created process */
|
||||
CTX_RESTORE_MSR_PC (NON_CRITICAL, 11); /* Restore MSR and PC */
|
||||
CTX_RESTORE_STATE_REGS (11); /* Restore state regs; Use 12 as temporary */
|
||||
CTX_RESTORE_REG (0); /* Restore all GP regs */
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (4);
|
||||
IRQ_RETURN_NON_CRITICAL;
|
||||
syscall_restore:
|
||||
CTX_RESTORE_MSR_IN_SYSCALL(11) ;
|
||||
CTX_RESTORE_STATE_REGS (11);
|
||||
CTX_RESTORE_REG (1);
|
||||
CTX_RESTORE_REG (2);
|
||||
CTX_RESTORE_GPREGS (13);
|
||||
li 3, 1; /* Return 1 indicating return from restore context */
|
||||
blr;
|
||||
|
||||
/*
|
||||
* Save context
|
||||
* - Saves only kernel context
|
||||
* - Invoked only from "suspend" (ISR saves its own context)
|
||||
* - Indicate ISRFLAG 0
|
||||
* - Pointer to process structure in r3
|
||||
* - Needs to save lesser context than an ISR. Only Dedicated and non-volatile registers need to be saved.
|
||||
* - The current processes stack will be continued to use for a while till a restore is done.
|
||||
*/
|
||||
|
||||
.global save_context
|
||||
.section .text
|
||||
.align 2
|
||||
.type save_context@function
|
||||
save_context:
|
||||
CTX_SAVE_MSR_IN_SYSCALL(12) ;
|
||||
CTX_SAVE_STATE_REGS (12); /* Save state registers using 12 as temporary */
|
||||
CTX_SAVE_REG (1);
|
||||
CTX_SAVE_REG (2);
|
||||
CTX_SAVE_GPREGS (13);
|
||||
li 12, 0;
|
||||
stb 12, ISRFLAG_OFFSET(BR); /* Save context always invoked from a system call */
|
||||
out_save_context:
|
||||
li 3, 0; /* Save context returns zero */
|
||||
blr;
|
||||
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------
|
||||
* Vector table.
|
||||
* FIXME -- Write some doc here
|
||||
*---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* common vector prologue. This has to be 4 instructions long to maintain
|
||||
alignment */
|
||||
|
||||
#define IVOR_PROLOGUE(ordinal, vector) \
|
||||
mtspr XREG_SPR_SPRG0_SU, 3; /* Save R3 */ \
|
||||
li 3, ordinal; \
|
||||
mtspr XREG_SPR_USPRG0, 3; /* Save ordinal */ \
|
||||
b vector;
|
||||
|
||||
.section ".vectors","ax"
|
||||
.globl _vectorbase
|
||||
.align 4 // 16 byte alignment to ensure the following IVORs are aligned correctly
|
||||
_vectorbase:
|
||||
/* Vector 0x00, Jump to zero. */
|
||||
IVOR0:
|
||||
IVOR_PROLOGUE (0, critical_irq);
|
||||
/* Vector 0x10, Machine Check Interrupt. */
|
||||
IVOR1:
|
||||
IVOR_PROLOGUE (1, machine_check_irq);
|
||||
/* Vector 0x20, Data Storage interrupt. */
|
||||
IVOR2:
|
||||
IVOR_PROLOGUE (2, non_critical_irq);
|
||||
/* Vector 0x30, Instruction Storage interrupt. */
|
||||
IVOR3:
|
||||
IVOR_PROLOGUE (3, non_critical_irq);
|
||||
/* Vector 0x40, External interrupt. */
|
||||
IVOR4:
|
||||
IVOR_PROLOGUE (4, kernel_irq);
|
||||
/* Vector 0x50, Alignment interrupt. */
|
||||
IVOR5:
|
||||
IVOR_PROLOGUE (5, non_critical_irq);
|
||||
/* Vector 0x60, Program Interrupt. */
|
||||
IVOR6:
|
||||
IVOR_PROLOGUE (6, non_critical_irq);
|
||||
/* Vector 0x70, FPU Unavailable interrupt. */
|
||||
IVOR7:
|
||||
IVOR_PROLOGUE (7, non_critical_irq);
|
||||
/* Vector 0x80, System Call Interrupt. */
|
||||
IVOR8: b system_call_handler
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
/* Vector 0x90, APU Available interrupt. */
|
||||
IVOR9:
|
||||
IVOR_PROLOGUE (9, non_critical_irq);
|
||||
/* Vector 0xA0, DEC interrupt. */
|
||||
IVOR10:
|
||||
IVOR_PROLOGUE (10, kernel_irq);
|
||||
/* Vector 0xB0, FIT interrupt. */
|
||||
IVOR11:
|
||||
IVOR_PROLOGUE (11, non_critical_irq);
|
||||
/* Vector 0xC0, Watchdog Timer interrupt.*/
|
||||
IVOR12:
|
||||
IVOR_PROLOGUE (12, critical_irq);
|
||||
/* Vector 0xD0, Data TLB Miss interrupt. */
|
||||
IVOR13:
|
||||
IVOR_PROLOGUE (13, non_critical_irq);
|
||||
/* Vector 0xE0, Instruction TLB Miss interrupt. */
|
||||
IVOR14:
|
||||
IVOR_PROLOGUE (14, non_critical_irq);
|
||||
/* Vector 0xF0, Debug interrupt. */
|
||||
IVOR15:
|
||||
IVOR_PROLOGUE (15, critical_irq);
|
||||
|
||||
.align 2
|
||||
|
||||
non_critical_irq:
|
||||
EXCEPTION_HANDLER (NON_CRITICAL)
|
||||
critical_irq:
|
||||
EXCEPTION_HANDLER (CRITICAL)
|
||||
machine_check_irq:
|
||||
EXCEPTION_HANDLER (CRITICAL) /* FIXME! Anything different here? */
|
||||
kernel_irq:
|
||||
IRQ_HANDLER (NON_CRITICAL)
|
304
lib/bsp/xilkernel/src/src/arch/ppc/ppc-hw.c
Executable file
304
lib/bsp/xilkernel/src/src/arch/ppc/ppc-hw.c
Executable file
|
@ -0,0 +1,304 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file ppc-hw.c
|
||||
//! PPC Hardware initialization
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <xparameters.h>
|
||||
#include <sys/process.h>
|
||||
#include <xil_exception.h>
|
||||
#include <xtime_l.h>
|
||||
#include <xpseudo_asm.h>
|
||||
#include <sys/syscall.h>
|
||||
#ifdef CONFIG_INTC
|
||||
#include <xintc.h>
|
||||
#endif
|
||||
#include <sys/decls.h>
|
||||
#ifndef PPC_CPU_440
|
||||
#include <xreg405.h>
|
||||
#else
|
||||
#include <xreg440.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifdef CONFIG_INTC
|
||||
XIntc sys_intc;
|
||||
#endif
|
||||
struct t_syscall_data system_call_data;
|
||||
// this pointer points to data shared between user and system
|
||||
struct t_syscall_data *system_call_data_ptr = &system_call_data;
|
||||
struct t_syscall_data **system_call_data_ptr_ptr = &system_call_data_ptr;
|
||||
unsigned int pit_timer_interval = 1; // default interval
|
||||
extern char did_resched;
|
||||
extern char timer_need_refresh;
|
||||
extern unsigned char sched_partial_tick;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void hw_init(void);
|
||||
void int_system_init(void);
|
||||
unsigned int pit_get_value(void);
|
||||
void pit_initialize(unsigned int interval);
|
||||
void pit_set_interval( unsigned int interval);
|
||||
void pit_reset(void);
|
||||
void pit_continue(void);
|
||||
void pit_disable(void);
|
||||
void setup_initial_context (process_struct *pcb, pid_t parent, unsigned int start_addr, unsigned int stackaddr, unsigned int stacksize);
|
||||
void init_idle_task (void);
|
||||
|
||||
extern void timer_int_handler(int) ;
|
||||
extern void system_call_handler(void *baseaddr);
|
||||
|
||||
#ifndef PPC_CPU_440
|
||||
|
||||
#define PIT_INT XIL_EXCEPTION_ID_PIT_INT
|
||||
#define PIT_SET_INTERVAL XTime_PITSetInterval
|
||||
#define PIT_ENABLE_AUTO_RELOAD XTime_PITEnableAutoReload
|
||||
#define PIT_DISABLE_INTR XTime_PITDisableInterrupt
|
||||
#define PIT_ENABLE_INTR XTime_PITEnableInterrupt
|
||||
#define PIT_CLEAR_STATUS() XTime_TSRClearStatusBits(XREG_TSR_PIT_INTERRUPT_STATUS)
|
||||
|
||||
#else
|
||||
|
||||
#define PIT_INT XIL_EXCEPTION_ID_DEC_INT
|
||||
#define PIT_SET_INTERVAL XTime_DECSetInterval
|
||||
#define PIT_ENABLE_AUTO_RELOAD XTime_DECEnableAutoReload
|
||||
#define PIT_DISABLE_INTR XTime_DECDisableInterrupt
|
||||
#define PIT_ENABLE_INTR XTime_DECEnableInterrupt
|
||||
#define PIT_CLEAR_STATUS() XTime_TSRClearStatusBits(XREG_TSR_DEC_INTERRUPT_STATUS)
|
||||
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - hw_init
|
||||
//! @desc
|
||||
//! PPC405 hardware specific initialization
|
||||
//! - Initialize PPC exception handling mechanism
|
||||
//! - If an interrupt controller is present, register interrupt controller handler
|
||||
//! as the external interrupt handler.
|
||||
//! - Register PPC timer interrupt handler as the handler for the PPC PIT interrupt
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void hw_init(void)
|
||||
{
|
||||
Xil_ExceptionInit(); // Initialize exception handling
|
||||
Xil_ExceptionDisable();
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
int_system_init();
|
||||
#endif
|
||||
|
||||
Xil_ExceptionRegisterHandler(PIT_INT, (Xil_ExceptionHandler)timer_int_handler, (void *)0); // Register PIT interrupt handler
|
||||
pit_initialize (SYSTMR_INTERVAL); // use SYSTMR_INTERVAL as configured in MSS
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - int_system_init
|
||||
//! @desc
|
||||
//! Initialize PPC405 interrupt handling system in the prescence of an interrupt controller.
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void int_system_init (void)
|
||||
{
|
||||
XStatus status;
|
||||
|
||||
status = XIntc_Initialize (&sys_intc, SYSINTC_DEVICE_ID);
|
||||
if (status != XST_SUCCESS) {
|
||||
DBG_PRINT ("XMK: init_int_system: XIntc_Initialize failed.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
XIntc_SetIntrSvcOption(SYSINTC_BASEADDR, XIN_SVC_ALL_ISRS_OPTION); // IntC ISR should service all interrupts
|
||||
Xil_ExceptionRegisterHandler (XIL_EXCEPTION_ID_NON_CRITICAL_INT, // Now tie the INTC's interrupt handler to the PPC Non-Critical Interrupt Handler
|
||||
|
||||
(Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,
|
||||
(void*)SYSINTC_DEVICE_ID);
|
||||
|
||||
status = XIntc_Start (&sys_intc, XIN_REAL_MODE); // Start the interrupt controller
|
||||
|
||||
if (status != XST_SUCCESS) {
|
||||
DBG_PRINT ("XMK: init_int_system: XIntc_Start failed.\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_INTC */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xmk_enter_kernel
|
||||
//! @desc
|
||||
//! Lock kernel by turning off ALL system interrupts
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - Locks kernel against ALL interrupts.
|
||||
//! - Does not lock against critical interrupts.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
inline void xmk_enter_kernel (void)
|
||||
{
|
||||
Xil_ExceptionDisable(); // Does not disable critical interrupt though
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xmk_leave_kernel
|
||||
//! @desc
|
||||
//! Unlock kernel by turning on system timer interrupts
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - Unlocks kernel with respect to ALL interrupts except critical interrupts
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
inline void xmk_leave_kernel( void )
|
||||
{
|
||||
Xil_ExceptionEnable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_initialize
|
||||
//! @desc
|
||||
//! Initialize the PIT timer in the system
|
||||
//! @param
|
||||
//! - interval is the interval to interrupt the system at.
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_initialize (unsigned int interval)
|
||||
{
|
||||
pit_timer_interval = interval;
|
||||
PIT_DISABLE_INTR ();
|
||||
PIT_SET_INTERVAL (interval);
|
||||
PIT_ENABLE_AUTO_RELOAD ();
|
||||
PIT_ENABLE_INTR ();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pit_reset
|
||||
//! @desc
|
||||
//! Enable and start PIT timer with configured PIT interval loaded to the PIT counter
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pit_reset (void)
|
||||
{
|
||||
// Refresh budget only if the timer ran out
|
||||
if (timer_need_refresh) {
|
||||
PIT_SET_INTERVAL (pit_timer_interval) ;
|
||||
PIT_ENABLE_AUTO_RELOAD () ;
|
||||
PIT_CLEAR_STATUS ();
|
||||
|
||||
// Reset scheduler/timer state
|
||||
did_resched = 0;
|
||||
timer_need_refresh = 0;
|
||||
sched_partial_tick = 0;
|
||||
} else {
|
||||
// FIXME!
|
||||
// - did_resched seems bogus. We will be here only if we do a resched
|
||||
// seems redundant. Leaving it in, because it is harmless if redundant
|
||||
if (did_resched) {
|
||||
did_resched = 0;
|
||||
sched_partial_tick = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the timer.
|
||||
PIT_ENABLE_INTR();
|
||||
}
|
||||
|
||||
void pit_disable (void)
|
||||
{
|
||||
PIT_DISABLE_INTR ();
|
||||
}
|
||||
|
||||
|
||||
void setup_initial_context (process_struct *pcb, pid_t parent, unsigned int start_addr, unsigned int stackaddr, unsigned int stacksize)
|
||||
{
|
||||
pcb->pcontext.isrflag = ISRFLAG_NEW_PROC;
|
||||
#ifndef PPC_CPU_440
|
||||
pcb->pcontext.regs[CTX_INDEX_MSR] = ptable[parent].pcontext.regs[CTX_INDEX_MSR] | XIL_EXCEPTION_NON_CRITICAL;
|
||||
#else
|
||||
// We set MSR[DS] = 1 here, because that is the TLB scheme we use to
|
||||
// separate instruction and data space on the 440.
|
||||
pcb->pcontext.regs[CTX_INDEX_MSR] = ptable[parent].pcontext.regs[CTX_INDEX_MSR] | XIL_EXCEPTION_NON_CRITICAL | XREG_MSR_TLB_DATA_TS;
|
||||
#endif
|
||||
pcb->pcontext.regs[CTX_INDEX_PC] = start_addr;
|
||||
pcb->pcontext.regs[CTX_INDEX_GPR(1)] = stackaddr;
|
||||
pcb->pcontext.regs[CTX_INDEX_GPR(2)] = ptable[parent].pcontext.regs[CTX_INDEX_GPR(2)];
|
||||
pcb->pcontext.regs[CTX_INDEX_GPR(13)] = ptable[parent].pcontext.regs[CTX_INDEX_GPR(13)];
|
||||
stacksize = 0; /* Dummy to remove compilation warnings */
|
||||
}
|
||||
|
||||
void init_idle_task (void)
|
||||
{
|
||||
idle_task_pid = proc_create (PRIO_LOWEST); // Idle task (PID 0).
|
||||
ptable[idle_task_pid].state = PROC_RUN; // Idle task assumed to be running as soon as the kernel starts
|
||||
#ifndef PPC_CPU_440
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_MSR] = mfmsr () | XIL_EXCEPTION_NON_CRITICAL;
|
||||
#else
|
||||
// We set MSR[DS] = 1 here, because that is the TLB scheme we use to
|
||||
// separate instruction and data space on the 440.
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_MSR] = mfmsr () | XIL_EXCEPTION_NON_CRITICAL | XREG_MSR_TLB_DATA_TS;
|
||||
#endif
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_PC] = (unsigned int)idle_task;
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_GPR(1)] = mfgpr (1);
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_GPR(2)] = mfgpr (2);
|
||||
ptable[idle_task_pid].pcontext.regs[CTX_INDEX_GPR(13)]= mfgpr (13);
|
||||
SET_CURRENT_PROCESS (idle_task_pid);
|
||||
}
|
100
lib/bsp/xilkernel/src/src/arch/ppc/timer_intr_handler.c
Executable file
100
lib/bsp/xilkernel/src/src/arch/ppc/timer_intr_handler.c
Executable file
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file timer_intr_handler.c
|
||||
//! Contains PPC system timer interrupt handler routine
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <xpseudo_asm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <xtime_l.h>
|
||||
|
||||
extern void soft_tmr_handler (void);
|
||||
extern signed char resched;
|
||||
extern process_struct *current_process;
|
||||
unsigned int kernel_ticks; //! Ticks since kernel startup
|
||||
char timer_need_refresh = 0; //! Do we need a reset?
|
||||
#ifdef CONFIG_STATS
|
||||
unsigned int budget_ticks;
|
||||
#endif
|
||||
unsigned char sched_partial_tick;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - timer_int_handler
|
||||
//! @desc
|
||||
//! System timer interrupt handler
|
||||
//! - Do a rescheduling operation
|
||||
//! - If a context switch occurs within this routine,
|
||||
//! - When returning out of process_scheduler, process executing will return in the appropriate
|
||||
//! context when it was switched out on a previous flow through this execution path.
|
||||
//! - Reset PIT interval to start a full time slice (if PIT in the system) (if INTC not present)
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - nothing
|
||||
//! @note
|
||||
//! - May NOT return from this routine if a NEW process context is scheduled in the scheduler
|
||||
//! - A context switch does not occur within this routine if an INTC is present. The switch
|
||||
//! occurs at the end of the INTC ISR.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void timer_int_handler (int irq_num)
|
||||
{
|
||||
irq_num = 0;
|
||||
// Update global kernel ticks so far
|
||||
kernel_ticks++;
|
||||
#ifdef CONFIG_STATS
|
||||
current_process->active_ticks++;
|
||||
budget_ticks++;
|
||||
#endif
|
||||
#ifdef CONFIG_TIME
|
||||
soft_tmr_handler ();
|
||||
#endif
|
||||
|
||||
if (sched_partial_tick) {
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
// Avoid one more starvation case. On a partial schedule tick,
|
||||
// you want to give the next full time quantum to the thread
|
||||
// which was scheduled partially and not any thread that
|
||||
// timed out in soft_tmr_handler.
|
||||
// Note: We do this only for RR scheduling where we don't
|
||||
// want starvation.
|
||||
resched = 0;
|
||||
#endif
|
||||
sched_partial_tick = 0;
|
||||
} else {
|
||||
resched = 1;
|
||||
}
|
||||
|
||||
timer_need_refresh = 1;
|
||||
}
|
59
lib/bsp/xilkernel/src/src/ipc/Makefile
Executable file
59
lib/bsp/xilkernel/src/src/ipc/Makefile
Executable file
|
@ -0,0 +1,59 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for ipc direcotry
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
OBJS = semaphore.o msg.o shm.o mutex.o
|
||||
INCLUDEDIR = ../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~
|
374
lib/bsp/xilkernel/src/src/ipc/msg.c
Executable file
374
lib/bsp/xilkernel/src/src/ipc/msg.c
Executable file
|
@ -0,0 +1,374 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file msg.c
|
||||
//! This contains functions handling the Message Queue functionality
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/kmsg.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/bufmalloc.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// The statically allocated message queues in the system
|
||||
msgid_ds msgq_heap[NUM_MSGQS] ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
msgid_ds* get_msgid_by_key( key_t key);
|
||||
extern void sys_buffree (membuf_t, void* mem);
|
||||
extern void* sys_bufmalloc (membuf_t, size_t size);
|
||||
extern void sys_buffree (membuf_t, void* mem);
|
||||
|
||||
#ifdef CONFIG_ENHANCED_MSGQ
|
||||
#define MSGQ_MALLOC(siz) malloc(siz)
|
||||
#define MSGQ_FREE(ptr) free(ptr)
|
||||
#else
|
||||
#define MSGQ_MALLOC(siz) sys_bufmalloc(MEMBUF_ANY, siz)
|
||||
#define MSGQ_FREE(ptr) sys_buffree(MEMBUF_ANY, ptr)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
msgid_ds* get_msgid_by_key (key_t key)
|
||||
{
|
||||
int i;
|
||||
msgid_ds *msgds = msgq_heap;
|
||||
|
||||
for (i=0; i<NUM_MSGQS; i++) {
|
||||
if ((msgds->msgid != -1) && // Structure valid
|
||||
(msgds->key == key)) // Key match
|
||||
return msgds;
|
||||
msgds++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_msgget
|
||||
//! @desc
|
||||
//! Get a Message Queue Identifier
|
||||
//! - Create a message queue identifier with key as the key, if IPC_CREAT is specified
|
||||
//! - If IPC_EXCL is also specified, then return the already existing message queue referenced by key
|
||||
//! - The message queue size is initialized based on the configuration specified
|
||||
//! @param
|
||||
//! - key is the unique key identifying this message queue
|
||||
//! - msgflg is the message queue creation flags ( IPC_CREAT, IPC_EXCL )
|
||||
//! @return
|
||||
//! - Return -1 on error. msgid of the created/retrieved message queue on success.
|
||||
//! errno set to,
|
||||
//! EEXIST - If a message queue identifier exists for the argument key but ((msgflg & IPC_CREAT) &&
|
||||
//! (msgflg & IPC_EXCL)) is non-zero.
|
||||
//! ENOENT - A message queue identifier does not exist for the argument key and (msgflg & IPC_CREAT)
|
||||
//! is 0.
|
||||
//! ENOSPC - If the message queue resources are exhausted
|
||||
//! @note
|
||||
//! - IPC_PRIVATE not supported yet.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_msgget (key_t key, int msgflg)
|
||||
{
|
||||
msgid_ds *msgds ;
|
||||
int i;
|
||||
|
||||
msgds = get_msgid_by_key (key);
|
||||
if (msgds != NULL) {
|
||||
if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
|
||||
kerrno = EEXIST;
|
||||
return -1; // Create requested, but msgq already exists
|
||||
}
|
||||
else if ((msgflg & IPC_CREAT))
|
||||
return msgds->msgid; // Return already existing msgq
|
||||
else return -1; // Unsupported msgflg
|
||||
}
|
||||
else if (key == IPC_PRIVATE)
|
||||
return -1;
|
||||
else { // msgds == NULL && key != IPC_PRIVATE
|
||||
if (!(msgflg & IPC_CREAT)) {
|
||||
kerrno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
msgds = msgq_heap;
|
||||
for (i=0; i<NUM_MSGQS; i++) {
|
||||
if (msgds->msgid == -1)
|
||||
break;
|
||||
msgds++ ;
|
||||
}
|
||||
|
||||
if (i == NUM_MSGQS) { // Message Queues exhausted
|
||||
kerrno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgds->msgid = i;
|
||||
msgds->key = key;
|
||||
if (sys_sem_init (&msgds->full, 0, msgds->msgq_len) < 0)
|
||||
return -1;
|
||||
if (sys_sem_init (&msgds->empty, 0, 0) < 0)
|
||||
return -1;
|
||||
|
||||
qinit (&msgds->msg_q);
|
||||
msgds->stats.msg_qnum = 0;
|
||||
msgds->stats.msg_lspid = 0;
|
||||
msgds->stats.msg_lrpid = 0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_msgctl
|
||||
//! @desc
|
||||
//! Control actions on a message queue
|
||||
//! - Check if operation requested on a valid message queue. Return error if not valid.
|
||||
//! - If cmd is IPC_STAT, return statistics in user level structure
|
||||
//! - If cmd is IPC_RMID, destroy this message queue. Destroy also forcibly terminates
|
||||
//! - all currently blocked processes. Also deallocates currently stored messages.
|
||||
//! @param
|
||||
//! - msgid is the msgid of the message queue
|
||||
//! - cmd is the operation requested
|
||||
//! - msqid_ds is the user level structure for storing stats
|
||||
//! @return
|
||||
//! - Return 0 on success. -1 on failure.
|
||||
//! errno set to,
|
||||
//! EINVAL - If msgid parameter refers to an invalid message queue or if cmd is invalid or if buf
|
||||
//! contains invalid parameters.
|
||||
//! @note
|
||||
//! - IPC_SET command not supported.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_msgctl (int msgid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
msgid_ds *msgds ;
|
||||
msg_t k_msg;
|
||||
int i;
|
||||
|
||||
if ((msgid < 0) || (msgid >= NUM_MSGQS) || (msgq_heap[msgid].msgid == -1)) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgds = &msgq_heap[msgid];
|
||||
|
||||
if (cmd == IPC_STAT) {
|
||||
if (buf == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
buf->msg_qnum = msgds->stats.msg_qnum; // Number of messages currently in the queue
|
||||
buf->msg_qbytes = msgds->stats.msg_qbytes; // Maximum number of bytes allowed in the queue
|
||||
buf->msg_lspid = msgds->stats.msg_lspid;
|
||||
buf->msg_lrpid = msgds->stats.msg_lrpid;
|
||||
}
|
||||
else if (cmd == IPC_RMID) {
|
||||
if (sem_force_destroy (&msgds->full) < 0)
|
||||
return -1;
|
||||
if (sem_force_destroy (&msgds->empty) < 0)
|
||||
return -1;
|
||||
|
||||
for (i=0; i < msgds->msg_q.item_count; i++) {
|
||||
deq (&msgds->msg_q,&k_msg,0);
|
||||
MSGQ_FREE (k_msg.msg_buf);
|
||||
msgds->msg_q.item_count--;
|
||||
}
|
||||
msgds->stats.msg_lspid = -1;
|
||||
msgds->stats.msg_lrpid = -1;
|
||||
msgds->msgid = -1 ;
|
||||
}
|
||||
else if (cmd == IPC_SET) {
|
||||
// Do nothing.
|
||||
// We are not supporting any of the fields that IPC_SET is capable of setting.
|
||||
// Also not flagging an error.
|
||||
}
|
||||
else {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_msgsnd
|
||||
//! @desc
|
||||
//! Send a message through a message queue
|
||||
//! - Allocate memory for the message inside the queue.
|
||||
//! - Copy the message and store information about the message in the queue.
|
||||
//! - If IPC_NOWAIT is specified and the queue is currently full then return -1.
|
||||
//! Wake up any process that is blocked on a msgrcv.
|
||||
//! @param
|
||||
//! - msgid -> msg ID of the message queue
|
||||
//! - msgp -> pointer to the message
|
||||
//! - msgsz -> size of the message
|
||||
//! - msgflg -> msgsnd control flags
|
||||
//! @return
|
||||
//! - Return 0 on success, -1 on failure. Fail if unable to allocate memory for message
|
||||
//! errno set to,
|
||||
//! EINVAL - The value of msgid is not a valid message queue identifier
|
||||
//! ENOSPC - The system could not allocate space for the message
|
||||
//! EIDRM - The message queue was removed from the system during the send operation
|
||||
//! @note
|
||||
//! - Messages are not stored based on POSIX specified message structure
|
||||
//! - (i.e. No assumption or use is made about/of a type field in the message)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_msgsnd (int msgid, const void *msgp, size_t msgsz, int msgflg)
|
||||
{
|
||||
msgid_ds *msgds ;
|
||||
msg_t k_msg;
|
||||
|
||||
if ((msgid < 0) || (msgid >= NUM_MSGQS) || (msgq_heap[msgid].msgid == -1)) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
k_msg.msg_buf = MSGQ_MALLOC (msgsz);
|
||||
k_msg.msg_len = msgsz;
|
||||
if (k_msg.msg_buf == NULL) { // Unable to allocate mem for message
|
||||
kerrno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgds = &msgq_heap[msgid];
|
||||
if ((msgflg & IPC_NOWAIT)) {
|
||||
if (sys_sem_trywait (&msgds->full) < 0) {
|
||||
MSGQ_FREE (k_msg.msg_buf);
|
||||
kerrno = EAGAIN;
|
||||
return -1; // Can't wait. Return and indicate unable to wait
|
||||
}
|
||||
} else {
|
||||
if (sys_sem_wait_x (&msgds->full) < 0) {
|
||||
MSGQ_FREE (k_msg.msg_buf);
|
||||
return -1; // sem_wait error
|
||||
}
|
||||
|
||||
if (msgq_heap[msgid].msgid == -1) { // The message queue was removed from the system during the send operation
|
||||
MSGQ_FREE (k_msg.msg_buf);
|
||||
kerrno = EIDRM;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (k_msg.msg_buf, msgp, msgsz); // Save the message
|
||||
enq (&msgds->msg_q, &k_msg, 0); // Enqueue the msg_t structure in the queue
|
||||
msgds->stats.msg_lspid = sys_get_currentPID ();
|
||||
msgds->stats.msg_qnum++;
|
||||
sys_sem_post (&msgds->empty); // Signal the consumer of mesg in Q
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_msgrcv
|
||||
//! @desc
|
||||
//! Receive a message through the message queue
|
||||
//! - If IPC_NOWAIT is specified, return immediately signalling error if no message is currently
|
||||
//! present
|
||||
//! - If the message in the queue is larger than the message size requested, then flag an error
|
||||
//! if MSG_NOERROR is not specified.
|
||||
//! - Copy the message into the user level buffer and deallocate the kernel message memory.
|
||||
//! - Wakeup any process blocked on a full message queue
|
||||
//! @param
|
||||
//! - msgid is the msg ID of the message queue
|
||||
//! - msgp is the pointer to the user level buffer
|
||||
//! - msgsz is the size requested in bytes
|
||||
//! - msgtyp is unused
|
||||
//! - msgflg is the flag controlling msgrcv
|
||||
//! @return
|
||||
//! - Return number of bytes actually copied. Return -1 on error
|
||||
//! errno set to,
|
||||
//! EINVAL - If msgid is not a valid message queue identifier
|
||||
//! EIDRM - If the message queue was removed from the system
|
||||
//! ENOMSG - msgsz is smaller than the size of the message in the queue
|
||||
//! @note
|
||||
//! - msgtyp IGNORED. Support only FIFO dequeueing of messages
|
||||
//! - i.e. messages not assumed to be of the following structure
|
||||
//! struct mymsg {
|
||||
//! long mtype; /* Message type. */
|
||||
//! char mtext[somesize]; /* Message text. */
|
||||
//! }
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
ssize_t sys_msgrcv (int msgid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
||||
{
|
||||
msgid_ds *msgds;
|
||||
msg_t k_msg;
|
||||
ssize_t nbytes;
|
||||
|
||||
if ((msgid < 0) || (msgid >= NUM_MSGQS) || (msgq_heap[msgid].msgid == -1)) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msgds = &msgq_heap[msgid] ;
|
||||
if (msgflg == IPC_NOWAIT) {
|
||||
if (sys_sem_trywait (&msgds->empty) < 0)
|
||||
return (ssize_t)-1 ;
|
||||
} else {
|
||||
if (sys_sem_wait_x (&msgds->empty) < 0)
|
||||
return (ssize_t)-1;
|
||||
|
||||
// Return here on unblock
|
||||
if (msgq_heap[msgid].msgid == -1) { // The message queue was removed from the system during the recv operation
|
||||
kerrno = EIDRM;
|
||||
return (ssize_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
deq (&msgds->msg_q, &k_msg, 0); // Get the msg_t structure from the Queue
|
||||
if (k_msg.msg_len > msgsz) {
|
||||
if (!(msgflg & MSG_NOERROR)) {
|
||||
MSGQ_FREE (k_msg.msg_buf); // Release message stored in the kernel
|
||||
kerrno = E2BIG; // user buffer too small to hold message
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
nbytes = msgsz;
|
||||
} else nbytes = k_msg.msg_len;
|
||||
|
||||
memcpy (msgp, k_msg.msg_buf, nbytes);
|
||||
msgds->stats.msg_lrpid = sys_get_currentPID ();
|
||||
msgds->stats.msg_qnum--;
|
||||
MSGQ_FREE (k_msg.msg_buf);
|
||||
sys_sem_post (&msgds->full); // Decrement the message count
|
||||
return (ssize_t)nbytes; // Return number of bytes saved
|
||||
}
|
||||
#endif /* CONFIG_MSGQ */
|
314
lib/bsp/xilkernel/src/src/ipc/mutex.c
Executable file
314
lib/bsp/xilkernel/src/src/ipc/mutex.c
Executable file
|
@ -0,0 +1,314 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mutex.c
|
||||
//! POSIX Mutex locks implementation
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/kpthread.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/decls.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//! Array of mutex structures. They are used to keep track of allocated
|
||||
//! mutex. Also used for other bookkeeping operations on Mutex.
|
||||
pthread_mutexinfo_t pthread_mutex_heap[MAX_PTHREAD_MUTEX] ; // Memory for allocating mutex
|
||||
pthread_mutexattr_t default_mutex_attr;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int pthread_mutex_lock_basic (pthread_mutex_t *mutex, int trylock);
|
||||
void pthread_mutex_heap_init (void);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pthread_mutex_heap_init(void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
|
||||
for (; i < MAX_PTHREAD_MUTEX; i++ ) {
|
||||
pthread_mutex_heap[i].is_allocated = 0;
|
||||
alloc_q (&(pthread_mutex_heap[i].mutex_wait_q), MAX_PTHREAD_MUTEX_WAITQ,
|
||||
PTHREAD_MUTEX_Q, sizeof(char), i) ;
|
||||
}
|
||||
default_mutex_attr.type = PTHREAD_MUTEX_DEFAULT;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_mutex_init
|
||||
//! @desc
|
||||
//! Initialize a pthread mutex
|
||||
//! - Allocate a pthread mutex structure.
|
||||
//! - Initialize the pthread mutex structure
|
||||
//! @param
|
||||
//! - mutex is the location to store mutex identifier in
|
||||
//! - attr is the mutex creation attributes. Unused currently.
|
||||
//! @return
|
||||
//! - Returns 0 on success and mutex identifier in *mutex.
|
||||
//! - Returns EAGAIN if no more mutex structures can be allocated.
|
||||
//! - Returns EINVAL if attr is invalid
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mutex == NULL)
|
||||
return -1;
|
||||
|
||||
if (attr == NULL)
|
||||
attr = &default_mutex_attr;
|
||||
|
||||
if (attr->type != PTHREAD_MUTEX_DEFAULT && attr->type != PTHREAD_MUTEX_RECURSIVE) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i < MAX_PTHREAD_MUTEX; i++) {
|
||||
if (pthread_mutex_heap[i].is_allocated == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_PTHREAD_MUTEX)
|
||||
return EAGAIN;
|
||||
|
||||
*mutex = (pthread_mutex_t)i;
|
||||
pthread_mutex_heap[i].is_allocated = 1;
|
||||
pthread_mutex_heap[i].locked = 0; // Unlocked
|
||||
pthread_mutex_heap[i].owner = -1;
|
||||
pthread_mutex_heap[i].attr.type = attr->type;
|
||||
|
||||
qinit (&(pthread_mutex_heap[i].mutex_wait_q));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_mutex_destroy
|
||||
//! @desc
|
||||
//! Destroy a pthread mutex
|
||||
//! - Check if a valid pthread mutex is being referenced
|
||||
//! - Deallocate it and set *mutex to an invalid value
|
||||
//! @param
|
||||
//! - mutex is the pointer to mutex identifier that is being referenced
|
||||
//! @return
|
||||
//! - Returns 0 on success
|
||||
//! - Returns EINVAL on invalid mutex reference
|
||||
//! @note
|
||||
//! - Mutex lock/unlock state disregarded during destroy. No consideration is given for
|
||||
//! waiting processes.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_mutex_destroy (pthread_mutex_t *mutex)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
if (mutex == NULL) // Verify parameter
|
||||
return EINVAL;
|
||||
|
||||
if (*mutex == PTHREAD_MUTEX_INITIALIZER) {
|
||||
*mutex = (pthread_mutex_t)PTHREAD_MUTEX_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*mutex >= MAX_PTHREAD_MUTEX)
|
||||
return EINVAL;
|
||||
|
||||
index = (unsigned int)*mutex;
|
||||
if (pthread_mutex_heap[index].is_allocated != 1)
|
||||
return EINVAL;
|
||||
|
||||
if (pthread_mutex_heap[index].locked != 0)
|
||||
return EBUSY;
|
||||
|
||||
pthread_mutex_heap[index].is_allocated = 0;
|
||||
*mutex = (pthread_mutex_t)PTHREAD_MUTEX_INVALID; // An invalid value
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pthread_mutex_lock_basic
|
||||
//! @desc
|
||||
//! Lock a mutex
|
||||
//! - If mutex has only been statically initialized, initialize with a call to pthread_mutex_init
|
||||
//! - If mutex is not already locked, lock it.
|
||||
//! - If mutex is locked, then if trylock is true, then return immediately with EBUSY. Block onto
|
||||
//! mutex wait queue if trylock is not true.
|
||||
//! - When the call returns the mutex is locked by the process that made the call
|
||||
//! - Ownership checks are performed if mutex type is PTHREAD_MUTEX_RECURSIVE
|
||||
//! - Recursive locks, cause the mutex lock count to be incremented.
|
||||
//! @param
|
||||
//! - mutex is the pointer to mutex identifier
|
||||
//! - trylock indicates if lock should just be tried for instead of committing to acquire the lock
|
||||
//! @return
|
||||
//! - Returns 0 on success and the mutex in a locked state.
|
||||
//! - Returns EBUSY if mutex locked and trylock requested. -1 on unhandled errors.
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int pthread_mutex_lock_basic (pthread_mutex_t *mutex, int trylock)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ((mutex == NULL) || // Verify parameters
|
||||
((*mutex != PTHREAD_MUTEX_INITIALIZER) &&
|
||||
(*mutex >= MAX_PTHREAD_MUTEX)))
|
||||
return EINVAL;
|
||||
|
||||
if (*mutex == PTHREAD_MUTEX_INITIALIZER) { // Initialize statically allocated mutex lock
|
||||
if (sys_pthread_mutex_init(mutex, &default_mutex_attr) != 0)
|
||||
return -1; // Undefined error code
|
||||
}
|
||||
|
||||
i = (unsigned int)*mutex;
|
||||
if (pthread_mutex_heap[i].is_allocated != 1)
|
||||
return EINVAL;
|
||||
|
||||
while (pthread_mutex_heap[i].locked) {
|
||||
if ((pthread_mutex_heap[i].attr.type != PTHREAD_MUTEX_RECURSIVE || // Suspend this request only if either of
|
||||
pthread_mutex_heap[i].owner != current_pid)) { // a. MUTEX type is not recursive
|
||||
if (trylock) // b. Requestor is not owner
|
||||
return EBUSY; // or both are true.
|
||||
else
|
||||
process_block (&(pthread_mutex_heap[i].mutex_wait_q), PROC_WAIT);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (pthread_mutex_heap[i].attr.type == PTHREAD_MUTEX_RECURSIVE)
|
||||
pthread_mutex_heap[i].locked++; // Lock with lock count incremented
|
||||
else
|
||||
pthread_mutex_heap[i].locked = 1; // Simple lock
|
||||
|
||||
pthread_mutex_heap[i].owner = current_pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_mutex_lock
|
||||
//! @desc
|
||||
//! Wrapper function for pthread_mutex_lock_basic routine, with trylock forced to 0.
|
||||
//! @param
|
||||
//! Same as pthread_mutex_lock_basic
|
||||
//! @return
|
||||
//! Same as pthread_mutex_lock_basic
|
||||
//! @note
|
||||
//! - Save code space by using same underlying implementation as sys_pthread_mutex_trylock
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_mutex_lock (pthread_mutex_t *mutex)
|
||||
{
|
||||
return pthread_mutex_lock_basic (mutex, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_mutex_lock
|
||||
//! @desc
|
||||
//! Wrapper function for pthread_mutex_lock_basic routine, with trylock forced to 1.
|
||||
//! @param
|
||||
//! Same as pthread_mutex_lock_basic
|
||||
//! @return
|
||||
//! Same as pthread_mutex_lock_basic
|
||||
//! @note
|
||||
//! - Save code space by using same underlying implementation as sys_pthread_mutex_lock
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_mutex_trylock (pthread_mutex_t *mutex)
|
||||
{
|
||||
return pthread_mutex_lock_basic (mutex, 1);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_mutex_unlock
|
||||
//! @desc
|
||||
//! Unlock a pthread mutex
|
||||
//! - If mutex has only been statically initialized, initialize with a call to pthread_mutex_init
|
||||
//! - Unlock the mutex. If there are processes waiting on the mutex, unblock a process
|
||||
//! according to the scheduling scheme
|
||||
//! - Ownership checks are performed if mutex type is PTHREAD_MUTEX_RECURSIVE
|
||||
//! - Recursive unlocks, cause the mutex lock count to be decremented.
|
||||
//! @param
|
||||
//! - mutex is the pointer to the mutex identifier
|
||||
//! @return
|
||||
//! - Returns 0 on success and mutex in unlocked state.
|
||||
//! - Returns -1 on undefined errors
|
||||
//! @note
|
||||
//! - No ownership checks, lock status etc. associated with XSI mutex types performed. This is the
|
||||
//! barebones mutex implementation
|
||||
//! - In SCHED_PRIO processes are unblocked 'highest priority first'.
|
||||
//! In SCHED_RR processes are unblocked in FIFO order.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_mutex_unlock (pthread_mutex_t *mutex)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if ((mutex == NULL) || // Verify parameter
|
||||
((*mutex != PTHREAD_MUTEX_INITIALIZER) &&
|
||||
(*mutex >= MAX_PTHREAD_MUTEX)))
|
||||
return EINVAL;
|
||||
|
||||
if (*mutex == PTHREAD_MUTEX_INITIALIZER) // Initialize statically allocated mutex lock
|
||||
if (sys_pthread_mutex_init(mutex, &default_mutex_attr) != 0)
|
||||
return -1;
|
||||
|
||||
i = (unsigned int)*mutex;
|
||||
if (pthread_mutex_heap[i].is_allocated != 1)
|
||||
return EINVAL;
|
||||
|
||||
if (pthread_mutex_heap[i].attr.type == PTHREAD_MUTEX_RECURSIVE) {
|
||||
if (pthread_mutex_heap[i].owner != current_pid)
|
||||
return EPERM;
|
||||
pthread_mutex_heap[i].locked--; // Unlock
|
||||
}
|
||||
else
|
||||
pthread_mutex_heap[i].locked = 0;
|
||||
|
||||
if (pthread_mutex_heap[i].locked == 0) {
|
||||
pthread_mutex_heap[i].owner = -1;
|
||||
if (pthread_mutex_heap[i].mutex_wait_q.item_count > 0)
|
||||
process_unblock (&(pthread_mutex_heap[i].mutex_wait_q));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PTHREAD_MUTEX */
|
558
lib/bsp/xilkernel/src/src/ipc/semaphore.c
Executable file
558
lib/bsp/xilkernel/src/src/ipc/semaphore.c
Executable file
|
@ -0,0 +1,558 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file semaphore.c
|
||||
//! Semaphore handling routines.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/init.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/decls.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/timer.h>
|
||||
#include <sys/xtrace.h>
|
||||
|
||||
#ifdef CONFIG_SEMA
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! Array of Semaphore structures. They are used to keep track of allocated
|
||||
//! semaphore's. Also used for other bookkeeping operations on Semaphore.
|
||||
|
||||
sem_info_t sem_heap[MAX_SEM]; // Memory for allocating semaphores
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
sem_map_t sem_map[MAX_SEM]; // Memory for mapping semaphores to symbolic names
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sem_heap_init (void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
|
||||
for (; i < MAX_SEM; i++ ) {
|
||||
sem_heap[i].sem_id = -1 ;
|
||||
sem_heap[i].owner = -1;
|
||||
sem_heap[i].unlink = 0;
|
||||
alloc_q (&sem_heap[i].sem_wait_q, MAX_SEM_WAITQ,
|
||||
SEM_Q, sizeof(char), i) ;
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
sem_map[i].sem = (sem_t)0;
|
||||
bzero ((void*)sem_map[i].name, SEM_NAME_MAX);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
sem_info_t* get_sem_by_semt (sem_t* sem)
|
||||
{
|
||||
if (sem == NULL)
|
||||
return NULL;
|
||||
if ((*sem < MAX_SEM) && (sem_heap[(unsigned int)*sem].sem_id != -1) )
|
||||
return &sem_heap[(unsigned int)*sem];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
sem_info_t* get_sem_by_name (char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_SEM; i++) {
|
||||
if (! strcmp(sem_map[i].name, name) && sem_heap[i].sem_id != -1)
|
||||
return &sem_heap[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sem_t* get_semt_by_name (char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<MAX_SEM; i++) {
|
||||
if (! strcmp(sem_map[i].name, name) && sem_heap[i].sem_id != -1)
|
||||
return &(sem_map[i].sem);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_NAMED_SEMA */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_init
|
||||
//! @desc
|
||||
//! Create a semaphore
|
||||
//! - Allocate a semaphore structure
|
||||
//! - Initialize semaphore value
|
||||
//! @param
|
||||
//! - sem is the location to store the created semaphore identifier
|
||||
//! - pshared indicates sharing semantics of this semaphore. Unused right now.
|
||||
//! - value is the initial value of the semaphore
|
||||
//! @return
|
||||
//! - Returns 0 on success and created semaphore identifier in *sem
|
||||
//! - Returns -1 on error
|
||||
//! errno set to,
|
||||
//! ENOSPC - If the system is out of resources to allocate another semaphore
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_init (sem_t* sem, int pshared, unsigned value)
|
||||
{
|
||||
signed char i = 0 ;
|
||||
|
||||
for (; i < MAX_SEM; i++) {
|
||||
if (sem_heap[i].sem_id == -1) {
|
||||
sem_heap[i].sem_id = i;
|
||||
sem_heap[i].sem_value = value;
|
||||
sem_heap[i].unlink = 0;
|
||||
qinit (&sem_heap[i].sem_wait_q);
|
||||
if (pshared == 0)
|
||||
sem_heap[i].owner = current_pid;
|
||||
else
|
||||
sem_heap[i].owner = -1; // Any process context can access the semaphore
|
||||
|
||||
*sem = (sem_t)i;
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
kerrno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_open
|
||||
//! @desc
|
||||
//! Creates a mapping between a name and a semaphore
|
||||
//! - Check whether named semaphore already exists, if so return a pointer to corresponding sem_t.
|
||||
//! - If the semaphore exists and O_EXCL also specified, return error.
|
||||
//! - If the semaphore does not exist, create it and map name to the semaphore, return sem_t*.
|
||||
//! @param
|
||||
//! - name is the name of the semaphore
|
||||
//! - oflag is the flag specifying open characteristics
|
||||
//! - mode is unused
|
||||
//! - value is the initial value of the semaphore
|
||||
//! @return
|
||||
//! - Returns a pointer to a sem_t corresponding to newly created or previously existing semaphore
|
||||
//! - Returns SEM_FAILED on errors
|
||||
//! errno set to,
|
||||
//! ENOSPC - If the system is out of resources to create a new semaphore (or mapping)
|
||||
//! EEXIST if O_EXCL has been requested and the named semaphore already exists.
|
||||
//! EINVAL if the parameters are invalid.
|
||||
//! @note
|
||||
//! - POSIX is vague about the behaviour of sem_open without O_CREAT in the flag. Therefore
|
||||
//! such oflags are not supported and SEM_FAILED returned.
|
||||
//! - Defined only if named semaphores are configured.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
sem_t* sys_sem_open (const char* name, int oflag, mode_t mode, unsigned value)
|
||||
{
|
||||
sem_t *sem;
|
||||
signed char i;
|
||||
|
||||
if (name == NULL || oflag != O_CREAT) {
|
||||
kerrno = EINVAL;
|
||||
return (sem_t*)SEM_FAILED;
|
||||
}
|
||||
|
||||
sem = get_semt_by_name ((char*)name);
|
||||
|
||||
if (sem != NULL) {
|
||||
if (oflag & O_EXCL) {
|
||||
kerrno = EEXIST;
|
||||
return (sem_t*)SEM_FAILED;
|
||||
}
|
||||
return sem;
|
||||
}
|
||||
|
||||
for (i=0; i<MAX_SEM; i++) { // No such named semaphore exists. Create one.
|
||||
if (sem_heap[i].sem_id == -1) {
|
||||
sem_heap[i].sem_id = i;
|
||||
sem_heap[i].sem_value = value;
|
||||
sem_heap[i].unlink = 0;
|
||||
qinit( &sem_heap[i].sem_wait_q);
|
||||
sem_heap[i].owner = -1; // Any process context can access the semaphore
|
||||
strcpy (sem_map[i].name, name); // Setup the name mapping
|
||||
sem_map[i].sem = (sem_t)i;
|
||||
return &(sem_map[i].sem) ;
|
||||
}
|
||||
}
|
||||
|
||||
kerrno = ENOSPC;
|
||||
return (sem_t*)SEM_FAILED;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_close
|
||||
//! @desc
|
||||
//! Close the semaphore referenced by sem
|
||||
//! @param
|
||||
//! - sem is the reference to the semaphore
|
||||
//! @return
|
||||
//! - 0 on success, -1 on error
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier is invalid
|
||||
//! ENOTSUP - If the semaphore is currently locked and processes are blocked on the semaphore
|
||||
//! @note
|
||||
//! - Defined only if named semaphores are configured.
|
||||
//! - Returns error if semaphore currently locked.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_close (sem_t* sem)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (seminfo->sem_value <= 0 && (seminfo->sem_wait_q.item_count > 0)) { // POSIX does not define semantics of destroying a currently locked semaphore
|
||||
kerrno = ENOTSUP; // We indicate error on such an operation.
|
||||
return -1;
|
||||
}
|
||||
bzero ((void*) sem_map[(int)seminfo->sem_id].name, SEM_NAME_MAX);
|
||||
sem_map[(int)seminfo->sem_id].sem = (sem_t)0;
|
||||
|
||||
seminfo->sem_id = -1;
|
||||
seminfo->sem_value = 0;
|
||||
seminfo->owner = -1;
|
||||
seminfo->unlink = 0;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_unlink
|
||||
//! @desc
|
||||
//! Unlink named semaphore
|
||||
//! - Check if named semaphore can be unlinked immediately
|
||||
//! - If yes, unlink, else indicate unlink required
|
||||
//! @param
|
||||
//! - name is the name of the semaphore
|
||||
//! @return
|
||||
//! - 0 on success, -1 on error
|
||||
//! errno set to,
|
||||
//! ENOENT - If an entry for name cannot be located
|
||||
//! @note
|
||||
//! - Defined only if named semaphores are configured.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_unlink (const char* name)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_name ((char*)name);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (seminfo->sem_value <= 0) { // Some process locking the semaphore currently.
|
||||
seminfo->unlink = 1; // Postpone unlink until all locks are released.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzero ((void*) sem_map[(int)seminfo->sem_id].name, SEM_NAME_MAX); // Else, unlink immediately
|
||||
sem_map[(int)seminfo->sem_id].sem = (sem_t)0;
|
||||
seminfo->sem_id = -1;
|
||||
seminfo->sem_value = 0;
|
||||
seminfo->owner = -1;
|
||||
seminfo->unlink = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NAMED_SEMA */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_getvalue
|
||||
//! @desc
|
||||
//! Get the current value of the semaphore
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! - sval is the location to store the semaphore value in
|
||||
//! @return
|
||||
//! - 0 on success, -1 on error.
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier does not refer to a valid semaphore
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_getvalue (sem_t* sem, int* sval)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if( seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*sval = seminfo->sem_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_wait_x
|
||||
//! @desc
|
||||
//! Semaphore wait operation
|
||||
//! - Decrement semaphore value
|
||||
//! - If value < 0, block
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! @return
|
||||
//! - 0 on success, -1 on failure
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier does not refer to a valid semaphore
|
||||
//! EIDRM - If the semaphore was removed forcibly
|
||||
//! @note
|
||||
//! - Renamed away from sys_sem_wait because it conflicts with functions in LWIP.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_wait_x (sem_t* sem)
|
||||
{
|
||||
sem_info_t* seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
seminfo->sem_value-- ; // Decrement the resource count
|
||||
if (seminfo->sem_value < 0) // If resource unavailable
|
||||
process_block (&(seminfo->sem_wait_q), PROC_WAIT);
|
||||
|
||||
// Return here on unblock
|
||||
|
||||
// Special. Not part of posix specification. If the semaphore was force_destroy'ed
|
||||
// then the process has not really acquired the semaphore when it was unblocked,
|
||||
// but rather it is in an interrupted situation. Signal error in this case
|
||||
|
||||
if (seminfo->sem_id == -1) { // If sem invalidated by now
|
||||
kerrno = EIDRM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_timedwait
|
||||
//! @desc
|
||||
//! Semaphore timedwait operation
|
||||
//! - Decrement semaphore value
|
||||
//! - If value < 0, block with a timeout, as specified by the second parameters 'ms'
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! - ms is the amount of time to be blocked on the semaphore in milliseconds
|
||||
//! @return
|
||||
//! - 0 on success, -1 on failure
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier does not refer to a valid semaphore
|
||||
//! ETIMEDOUT - The semaphore could not be locked before the specified timeout expired.
|
||||
//! EIDRM - If the semaphore was forcibly removed from the system
|
||||
//! @note
|
||||
//! - Depends on CONFIG_TIME being true
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_timedwait (sem_t* sem, unsigned int ms)
|
||||
{
|
||||
sem_info_t* seminfo = get_sem_by_semt (sem);
|
||||
process_struct *self;
|
||||
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
seminfo->sem_value-- ; // Decrement the resource count
|
||||
if (seminfo->sem_value < 0) { // If resource unavailable
|
||||
self = current_process;
|
||||
add_tmr (self->pid, ms); // Add a timer for self
|
||||
process_block (&(seminfo->sem_wait_q), PROC_TIMED_WAIT);
|
||||
|
||||
// Return here on unblock
|
||||
if (self->timeout) { // Timeout during semaphore wait. Return with error
|
||||
seminfo->sem_value++; // Restore sem value
|
||||
self->timeout = 0;
|
||||
kerrno = ETIMEDOUT;
|
||||
return -1;
|
||||
} else {
|
||||
remove_tmr (self->pid); // We managed to acquire the semaphore. Remove associated timer
|
||||
}
|
||||
}
|
||||
|
||||
// Special. Not part of posix specification. If the semaphore was force_destroy'ed
|
||||
// then the process has not really acquired the semaphore when it was unblocked,
|
||||
// but rather it is in an interrupted situation. Signal error in this case
|
||||
|
||||
if (seminfo->sem_id == -1) { // If sem invalidated by now
|
||||
kerrno = EIDRM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
#endif /* CONFIG_TIME */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_trywait
|
||||
//! @desc
|
||||
//! Try wait operation on a semaphore
|
||||
//! - Check if semaphore can be locked. If so, lock it, else return -1
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! @return
|
||||
//! - Return 0 on success, -1 on failure
|
||||
//! errno set to,
|
||||
//! EINVAL - The semaphore identifier does not refer to a valid semaphore
|
||||
//! EAGAIN - The semaphore could not be immediately locked by trywait
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_trywait (sem_t *sem)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (seminfo->sem_value > 0) {
|
||||
seminfo->sem_value-- ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
kerrno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_post
|
||||
//! @desc
|
||||
//! Semaphore post operation
|
||||
//! - Increment semaphore value
|
||||
//! - If semaphore value <= 0, unblock a waiting process (depending on scheduling type)
|
||||
//! - If semaphore value > 0 and if unlink requested, destroy the semaphore
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! @return
|
||||
//! - Return 0 on success, -1 on failure
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier does not refer to a valid semaphore
|
||||
//! @note
|
||||
//! - process_unblock unblocks the highest prio process in the queue in case of SCHED_PRIO.
|
||||
//! Else, the first process in the queue is unblocked.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_post (sem_t* sem)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
seminfo->sem_value++;
|
||||
if ((seminfo->sem_value <= 0) && (seminfo->sem_wait_q.item_count > 0))
|
||||
process_unblock (&(seminfo->sem_wait_q));
|
||||
else if ((seminfo->sem_value > 0) && (seminfo->unlink)) // Additionally, unlink the semaphore, if unlink is set
|
||||
sys_sem_destroy (sem);
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sem_destroy
|
||||
//! @desc
|
||||
//! Destroy a semaphore
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! @return
|
||||
//! - Return 0 on success, -1 on failure
|
||||
//! errno set to,
|
||||
//! EINVAL - If the semaphore identifier does not refer to a valid semaphore
|
||||
//! EBUSY - If the semaphore is currently locked and processes are blocked on it
|
||||
//! @note
|
||||
//! - Returns error if semaphore currently locked.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_sem_destroy (sem_t* sem)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((seminfo->sem_value <= 0) && (seminfo->sem_wait_q.item_count > 0)) {
|
||||
// POSIX does not define semantics of destroying a semaphore that has blocked processes
|
||||
kerrno = EBUSY; // We indicate error on such an operation
|
||||
return -1;
|
||||
}
|
||||
|
||||
seminfo->sem_id = -1;
|
||||
seminfo->sem_value = 0;
|
||||
seminfo->owner = -1;
|
||||
seminfo->unlink = 0;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sem_force_destroy
|
||||
//! @desc
|
||||
//! Destroy a semaphore and force waiting processes out of the semaphore
|
||||
//! @param
|
||||
//! - sem is the semaphore reference
|
||||
//! @return
|
||||
//! - Return 0 on success, -1 on failure
|
||||
//! @note
|
||||
//! - This is not a system call and is for kernel use only.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sem_force_destroy (sem_t* sem)
|
||||
{
|
||||
sem_info_t *seminfo = get_sem_by_semt (sem);
|
||||
if (seminfo == NULL)
|
||||
return -1;
|
||||
|
||||
while (seminfo->sem_value <= 0 && (seminfo->sem_wait_q.item_count > 0)) { // Unblock waiting processes and continue
|
||||
process_unblock (&seminfo->sem_wait_q);
|
||||
seminfo->sem_value++;
|
||||
}
|
||||
|
||||
seminfo->sem_id = -1;
|
||||
seminfo->sem_value = 0;
|
||||
seminfo->owner = -1;
|
||||
seminfo->unlink = 0;
|
||||
return 0 ;
|
||||
}
|
||||
#endif /* CONFIG_SEMA */
|
263
lib/bsp/xilkernel/src/src/ipc/shm.c
Executable file
263
lib/bsp/xilkernel/src/src/ipc/shm.c
Executable file
|
@ -0,0 +1,263 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file shm.c
|
||||
//! POSIX Shared memory implementation
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/kshm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! Array of Shared Memory structures. They are used to keep track of allocated
|
||||
//! Shared mem's. Also used for other bookkeeping operations on shared mem.
|
||||
shm_info_t shm_heap[N_SHM] ;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
shm_info_t* get_shm_by_key (key_t key);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
shm_info_t* get_shm_by_key (key_t key)
|
||||
{
|
||||
int i;
|
||||
shm_info_t* shmds = shm_heap;
|
||||
|
||||
for (i=0; i<N_SHM; i++) {
|
||||
if ((shmds->shm_id != -1) && // Structure valid
|
||||
(shmds->shm_key == key)) // Key match
|
||||
return shmds;
|
||||
shmds++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_shmget
|
||||
//! @desc
|
||||
//! Create a new shared memory segment based on key
|
||||
//! - If creation flags are IPC_CREAT then the shm_id of the shared memory segment created/retrieved
|
||||
//! is returned.
|
||||
//! - If the shared memory already exists and IPC_EXCL is specified, -1 is returned
|
||||
//! - Atleast one of the shared memory segments available in the system must EXACTLY
|
||||
//! match the requested size.
|
||||
//! - If creating a new segment, initialize memory to zero.
|
||||
//! @param
|
||||
//! - key is the unique key representing the segment
|
||||
//! - size is the requested shared memory size
|
||||
//! - shmflg is the creation flag
|
||||
//! @return
|
||||
//! - Returns 0 on success, -1 on error
|
||||
//! errno set to,
|
||||
//! EEXIST - A shared memory identifier exists for the argument key but
|
||||
//! (shmflg &IPC_CREAT) && (shmflg &IPC_EXCL) is non-zero
|
||||
//! ENOTSUP - Unsupported shmflg
|
||||
//! ENOENT - A shared memory identifier does not exist for the argument key and (shmflg &IPC_CREAT)
|
||||
//! is 0
|
||||
//! @note
|
||||
//! - IPC_PRIVATE is not supported. Size restrictions exist based on system configuration.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_shmget (key_t key, size_t size, int shmflg)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
shm_info_t *shmds ;
|
||||
|
||||
shmds = get_shm_by_key (key);
|
||||
|
||||
if (shmds != NULL) {
|
||||
if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
|
||||
kerrno = EEXIST; // Create requested, but shm already exists
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return shmds->shm_id; // Return already existing shm
|
||||
} else if (key == IPC_PRIVATE) {
|
||||
kerrno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
else { // shmds == NULL && key != IPC_PRIVATE
|
||||
if (!(shmflg & IPC_CREAT)) {
|
||||
kerrno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
shmds = shm_heap;
|
||||
for (i=0; i<N_SHM; i++) {
|
||||
if ((shmds->shm_id == -1) && (shmds->shm_segsz == size)) // Use only matching shm allocations
|
||||
break;
|
||||
shmds++ ;
|
||||
}
|
||||
|
||||
if (i == N_SHM) { // Out of resources
|
||||
kerrno = ENOSPC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
shmds->shm_id = i;
|
||||
shmds->shm_key = key;
|
||||
shmds->shm_nattch = 0;
|
||||
shmds->shm_lpid = -1;
|
||||
shmds->shm_cpid = current_pid;
|
||||
bzero ((void *)shmds->shm_addr, shmds->shm_segsz); // POSIX requires mem to be initialized to zero.
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_shmctl
|
||||
//! @desc
|
||||
//! Control the shared memory
|
||||
//! - if cmd is IPC_STAT store the statistics for this shared memory segment in buf
|
||||
//! - if cmd is IPC_RMID remove this shared memory segment from the system
|
||||
//! @param
|
||||
//! - shmid is the ID of the shared memory segment
|
||||
//! - cmd is the shm command
|
||||
//! - buf is the store area for shm statistics
|
||||
//! @return
|
||||
//! - Returns 0 on success and -1 on error
|
||||
//! errno set to,
|
||||
//! EINVAL if shmid refers to an invalid shared memory segment or cmd or other params are invalid.
|
||||
//! @note
|
||||
//! - IPC_SET is not supported.
|
||||
//! - On an IPC_RMID operation, no notification is sent to processes still attached to the segment
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_shmctl (int shmid, int cmd, struct shmid_ds* buf)
|
||||
{
|
||||
shm_info_t* shmds ;
|
||||
|
||||
if ((shmid < 0) || (shmid >= N_SHM) || (shm_heap[shmid].shm_id == -1)) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
shmds = &shm_heap[shmid] ;
|
||||
if (cmd == IPC_STAT) {
|
||||
if (buf == NULL) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
buf->shm_segsz = shmds->shm_segsz;
|
||||
buf->shm_lpid = shmds->shm_lpid;
|
||||
buf->shm_cpid = shmds->shm_cpid;
|
||||
buf->shm_nattch = shmds->shm_nattch;
|
||||
} else if (cmd == IPC_SET) {
|
||||
// Do nothing. We don't support it, but we don't flag an error either.
|
||||
} else if (cmd == IPC_RMID) {
|
||||
shmds->shm_id = -1; // Attached processes can still carry on
|
||||
shmds->shm_nattch = 0;
|
||||
} else {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_shmat
|
||||
//! @desc
|
||||
//! Attach to shared memory segment
|
||||
//! - Lookup shared memory segment based on shmid and return pointer to start of the segment
|
||||
//! @param
|
||||
//! - shmid is the ID of the segment
|
||||
//! - shmaddr is the address specification of the segment (ignored)
|
||||
//! - shmflg is the attach flag (ignored)
|
||||
//! @return
|
||||
//! - Return the address of the segment on success and NULL on error.
|
||||
//! errno set to,
|
||||
//! EINVAL if shmid refers to an invalid shared memory segment
|
||||
//! @note
|
||||
//! - The shmaddr specification is discarded. We support attaches only to the start of the segment.
|
||||
//! No memory mapping of any kind is done.
|
||||
//! - shmflg is ignored because it applies to shmaddr
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void* sys_shmat (int shmid, const void *shmaddr, int flag)
|
||||
{
|
||||
if ((shmid < 0) || (shmid >= N_SHM) || (shm_heap[shmid].shm_id == -1)) {
|
||||
kerrno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shm_heap[shmid].shm_nattch++ ;
|
||||
shm_heap[shmid].shm_lpid = sys_get_currentPID();
|
||||
return (void*)(shm_heap[shmid].shm_addr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_shmdt
|
||||
//! @desc
|
||||
//! Detach from shared memory segment
|
||||
//! @param
|
||||
//! - shmaddr is the address of the shared memory segment that is to be detached from
|
||||
//! @return
|
||||
//! - Return's 0 on success and -1 on error.
|
||||
//! errno set to,
|
||||
//! EINVAL if shmaddr is not within any of the available shared memory segments.
|
||||
//! @note
|
||||
//! - None.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_shmdt (const void *shmaddr)
|
||||
{
|
||||
shm_info_t* shmds;
|
||||
unsigned int i = 0;
|
||||
|
||||
shmds = shm_heap;
|
||||
for (; i < N_SHM; i++) {
|
||||
if ((char *)shmds->shm_addr == (char *)shmaddr)
|
||||
break ;
|
||||
shmds++ ;
|
||||
}
|
||||
if (i == N_SHM) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
shmds->shm_nattch--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SHM */
|
59
lib/bsp/xilkernel/src/src/sys/Makefile
Executable file
59
lib/bsp/xilkernel/src/src/sys/Makefile
Executable file
|
@ -0,0 +1,59 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for sys directory
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:51 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
OBJS = init.o alloc.o queue.o process.o sched.o xilkernel_main.o mem.o timer.o pthread.o intr.o elf.o bufmalloc.o syscall.o xtrace.o
|
||||
INCLUDEDIR = ../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -c $< -D__ASM__ -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~
|
57
lib/bsp/xilkernel/src/src/sys/alloc.c
Executable file
57
lib/bsp/xilkernel/src/src/sys/alloc.c
Executable file
|
@ -0,0 +1,57 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file alloc.c
|
||||
//! Kernel data structures to be allocated in the BSS section.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/arch.h>
|
||||
|
||||
#if PTHREAD_STACK_SIZE < 1024
|
||||
#define KERNEL_IRQ_STACKSZ 1024
|
||||
#else
|
||||
#define KERNEL_IRQ_STACKSZ PTHREAD_STACK_SIZE
|
||||
#endif
|
||||
|
||||
//! kernel_irq_stack - Stack to be used on IRQs
|
||||
char kernel_irq_stack[KERNEL_IRQ_STACKSZ] __attribute__ ((aligned (STACK_ALIGN)));
|
||||
const char *kernel_irq_stack_ptr = (const char *)(kernel_irq_stack + KERNEL_IRQ_STACKSZ + SSTACK_PTR_ADJUST);
|
||||
const char *kernel_irq_stack_ptr_end = (const char *)(kernel_irq_stack + SSTACK_PTR_ADJUST);
|
||||
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
//! process_startup_stack - Temporary initial stack to be used by processes
|
||||
//! before their own elf stacks are setup. This is potentially dangerous
|
||||
char process_startup_stack[PROCESS_STARTUP_STACKSZ] __attribute__ ((aligned (STACK_ALIGN)));
|
||||
#endif
|
231
lib/bsp/xilkernel/src/src/sys/bufmalloc.c
Executable file
231
lib/bsp/xilkernel/src/src/sys/bufmalloc.c
Executable file
|
@ -0,0 +1,231 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file bufmalloc.c
|
||||
//! Block memory allocation support
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <stdio.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/init.h>
|
||||
#include <errno.h>
|
||||
#include <sys/bufmalloc.h>
|
||||
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#define MEM_TO_BLK(membufp, mem) (((unsigned int)mem - (unsigned int)membufp->memptr)/(membufp->blksiz))
|
||||
#define MEM_WITHIN_BUF(membufp, mem) (((mem >= membufp->memptr) && (mem < membufp->limit))?1:0)
|
||||
|
||||
typedef struct membuf_info_s {
|
||||
char active;
|
||||
void *memptr;
|
||||
void *limit;
|
||||
void *freep;
|
||||
int nblks;
|
||||
int nfree;
|
||||
size_t blksiz;
|
||||
} membuf_info_t;
|
||||
|
||||
void* get_mbufblk (membuf_info_t *mbufptr);
|
||||
extern void bufmalloc_mem_init (void);
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
membuf_info_t mbufheap[N_MBUFS];
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void bufmalloc_init (void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < N_MBUFS; i++)
|
||||
mbufheap[i].active = 0;
|
||||
|
||||
bufmalloc_mem_init ();
|
||||
}
|
||||
|
||||
void* get_mbufblk (membuf_info_t *mbufptr)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (!mbufptr->nfree)
|
||||
return NULL;
|
||||
|
||||
ret = mbufptr->freep;
|
||||
mbufptr->freep = (*(void**)ret);
|
||||
mbufptr->nfree--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_bufcreate
|
||||
//! @desc
|
||||
//! Free the memory allocated by bufmalloc
|
||||
//! @param
|
||||
//! - mem is the address of the memory block, that was got from bufmalloc
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - WARNING. ALIGNMENT requirements have to be met or exception handlers required.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz)
|
||||
{
|
||||
int i;
|
||||
membuf_info_t *mbufptr;
|
||||
void **cur, **next;
|
||||
|
||||
if ((mbuf == NULL) || (memptr == NULL) || (nblks <= 0) || (blksiz < sizeof (void*))) {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbufptr = &mbufheap[0];
|
||||
for (i = 0; i < N_MBUFS; i++) { // Find first free membuf descriptor
|
||||
if (!mbufptr->active)
|
||||
break;
|
||||
mbufptr++;
|
||||
}
|
||||
|
||||
if (i == N_MBUFS) {
|
||||
kerrno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbufptr->active = 1;
|
||||
mbufptr->memptr = memptr;
|
||||
mbufptr->nblks = nblks;
|
||||
mbufptr->blksiz = blksiz;
|
||||
mbufptr->nfree = nblks;
|
||||
mbufptr->freep = memptr;
|
||||
mbufptr->limit = (void*)((unsigned int)memptr + (nblks * blksiz));
|
||||
*mbuf = (membuf_t)i; // Return membuf identifier
|
||||
|
||||
cur = (void**)memptr;
|
||||
next = (void**)((unsigned int)memptr + blksiz);
|
||||
for (i = 0; i < (nblks - 1); i++) { // Initialize free list in the the memory block
|
||||
*cur = (void*)next; // Alignment constraints should be met here
|
||||
cur = next; // Otherwise, unaligned exceptions will occur
|
||||
next = (void**)((unsigned int)next + blksiz);
|
||||
}
|
||||
*cur = (void*) NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_bufdestroy (membuf_t mbuf)
|
||||
{
|
||||
if (mbuf >= 0 && mbuf < N_MBUFS)
|
||||
mbufheap[mbuf].active = 0;
|
||||
else {
|
||||
kerrno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* sys_bufmalloc (membuf_t mbuf, size_t siz)
|
||||
{
|
||||
membuf_info_t *mbufptr;
|
||||
void* ret = NULL;
|
||||
int i;
|
||||
|
||||
if ((mbuf != MEMBUF_ANY) && ((mbuf < 0 || mbuf > N_MBUFS)))
|
||||
return NULL;
|
||||
|
||||
if (mbuf == MEMBUF_ANY) {
|
||||
mbufptr = &mbufheap[0];
|
||||
for (i = 0; i < N_MBUFS; i++) {
|
||||
if (mbufptr->active && mbufptr->blksiz >= siz) { // Get first pool that can fit the request
|
||||
ret = get_mbufblk (mbufptr);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
mbufptr++;
|
||||
}
|
||||
} else {
|
||||
mbufptr = &mbufheap[mbuf];
|
||||
|
||||
if (!mbufptr->active) {
|
||||
kerrno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
ret = get_mbufblk (mbufptr);
|
||||
}
|
||||
|
||||
if (ret == NULL)
|
||||
kerrno = EAGAIN;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sys_buffree (membuf_t mbuf, void *mem)
|
||||
{
|
||||
membuf_info_t *mbufptr;
|
||||
void** newblk;
|
||||
int blk, i;
|
||||
|
||||
if ((mbuf != MEMBUF_ANY) && ((mbuf < 0 || mbuf > N_MBUFS)))
|
||||
return;
|
||||
|
||||
if (mbuf == MEMBUF_ANY) {
|
||||
mbufptr = &mbufheap[0];
|
||||
for (i = 0; i < N_MBUFS; i++) {
|
||||
if (mbufptr->active && MEM_WITHIN_BUF (mbufptr, mem))
|
||||
break;
|
||||
mbufptr++;
|
||||
}
|
||||
if (i == N_MBUFS)
|
||||
return;
|
||||
} else
|
||||
mbufptr = &mbufheap[mbuf];
|
||||
|
||||
blk = MEM_TO_BLK (mbufptr, mem);
|
||||
if (blk < 0 || blk > mbufptr->nblks)
|
||||
return;
|
||||
|
||||
newblk = (void**)((unsigned int)mbufptr->memptr +
|
||||
(mbufptr->blksiz * blk)); // Forcing it to be a valid chain offset within the block
|
||||
|
||||
*newblk = mbufptr->freep;
|
||||
mbufptr->freep = (void*)newblk;
|
||||
mbufptr->nfree++;
|
||||
}
|
||||
#endif /* CONFIG_BUFMALLOC */
|
135
lib/bsp/xilkernel/src/src/sys/elf.c
Executable file
135
lib/bsp/xilkernel/src/src/sys/elf.c
Executable file
|
@ -0,0 +1,135 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file elf.c
|
||||
//! ELF file related routines (Creating processes out of ELF files)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/init.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/stats.h>
|
||||
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
#include <sys/kpthread.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
extern process_struct ptable[] ;
|
||||
extern signed char current_pid;
|
||||
extern char process_startup_stack[];
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_elf_process_create
|
||||
//! @desc
|
||||
//! Process creation.
|
||||
//! - Reserves a pid for the process.
|
||||
//! - Initilaizes the process structure. Also loads the r15 with the start
|
||||
//! address of the process.
|
||||
//! - Places the process in the READY_Q.
|
||||
//! - If SCHED_PRIO, calls the process_scheduler for scheduling.
|
||||
//!
|
||||
//! @param
|
||||
//! - pstart_addr is the start address of the process
|
||||
//! - priority is the priority of the process
|
||||
//! @return
|
||||
//! - PID of the new process.
|
||||
//! - -1 on Error. Max. process exceeded.
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
pid_t sys_elf_process_create (void* pstart_addr, unsigned int priority)
|
||||
{
|
||||
pid_t pid;
|
||||
process_struct *pcb;
|
||||
unsigned int stackaddr;
|
||||
|
||||
pid = proc_create (priority);
|
||||
|
||||
if (pid == -1)
|
||||
return -1;
|
||||
|
||||
pcb = &ptable[pid];
|
||||
|
||||
stackaddr = ((unsigned int)process_startup_stack // Temporary stack for new launched process in case it is interrupted
|
||||
+ PROCESS_STARTUP_STACKSZ + SSTACK_PTR_ADJUST); // before its own stack is setup
|
||||
|
||||
setup_initial_context (&ptable[pid], current_pid, pstart_addr, stackaddr, 0);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_elf_exit
|
||||
//! @desc
|
||||
//! Remove the process entry from the process table.
|
||||
//! - Set the is_allocated flag to '0'. Set the current_pid to -1. so that the
|
||||
//! next process gets scheduled.
|
||||
//! @return
|
||||
//! - 0 on Success
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_elf_exit()
|
||||
{
|
||||
process_invalidate (&ptable[current_pid]);
|
||||
suspend ();
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ELF_PROCESS */
|
40
lib/bsp/xilkernel/src/src/sys/init.c
Executable file
40
lib/bsp/xilkernel/src/src/sys/init.c
Executable file
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file init.c
|
||||
//! This contains the values for system definition. This can be
|
||||
//! generated by libgen and can also be modified by the user for customization.
|
||||
//! - The structures are declared in sys/init.h
|
||||
//! - If any changes are made to this file by the user, then they also need
|
||||
//! to change the corresponding fields in config_cparam.h file.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <config/config_init.h>
|
215
lib/bsp/xilkernel/src/src/sys/intr.c
Executable file
215
lib/bsp/xilkernel/src/src/sys/intr.c
Executable file
|
@ -0,0 +1,215 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file intr.c
|
||||
//!
|
||||
//! XMK API for registering and managing interrupt handlers for device
|
||||
//! interrupts. Depends on an interrupt controller being present in the system
|
||||
//! @note - We need to add more thread specific context switch (such as __errno) before invoking
|
||||
//! user interrupt handlers
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
#include <xparameters.h>
|
||||
#include <sys/intr.h>
|
||||
#include <xintc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/decls.h>
|
||||
|
||||
|
||||
//! Interrupt descriptor for each interrupt
|
||||
typedef struct intr_desc_s {
|
||||
XInterruptHandler handler;
|
||||
void *callback;
|
||||
pid_t pid;
|
||||
} intr_desc_t;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
unsigned int sys_register_int_handler (int_id_t intr_id, void (*handler)(void*), void *callback);
|
||||
void sys_unregister_int_handler (int_id_t intr_id);
|
||||
void sys_enable_interrupt (int_id_t intr_id);
|
||||
void sys_disable_interrupt (int_id_t intr_id);
|
||||
void sys_acknowledge_interrupt (int_id_t intr_id);
|
||||
void irq_wrapper (void* intr_id);
|
||||
|
||||
extern XIntc sys_intc;
|
||||
extern void setup_usr_irq_context (pid_t pid);
|
||||
extern void restore_kernel_context (void);
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#if 0
|
||||
intr_desc_t idt[XPAR_INTC_MAX_NUM_INTR_INPUTS];
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#if 0 // Not being used currently
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - irq_wrapper
|
||||
//! @desc
|
||||
//! Set and unset appropriate context before invoking user level interrupt handlers. The exact context
|
||||
//! to be saved and restored is architecture specific.
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void irq_wrapper (void* intr_id)
|
||||
{
|
||||
int_id_t id = (int_id_t)((unsigned int)(intr_id) & 0xff);
|
||||
setup_usr_irq_context (idt[id].pid); //! Setup context for user-level interrupt handler
|
||||
idt[id].handler (idt[id].callback); //! Invoke handler
|
||||
restore_kernel_context (); //! Restore kernel context
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_register_int_handler
|
||||
//! @desc
|
||||
//! Register a handler with the interrupt controller for the specified interrupt
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! - handler is the requested handler
|
||||
//! - callback is a pointer to a callback value
|
||||
//! @return
|
||||
//! - return XST_SUCCESS (defined in xstatus.h) on success.
|
||||
//! - return -1 in MB_XILKERNEL, if trying to register a handler for the system timer interrupt.
|
||||
//! - Other error codes on failure (look at xstatus.h for other error codes)
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
unsigned int sys_register_int_handler (int_id_t intr_id, void (*handler)(void*), void *callback)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
// Disallow playing with timer interrupt
|
||||
if (intr_id == SYSTMR_INTR_ID )
|
||||
return (unsigned int)-1;
|
||||
#endif
|
||||
|
||||
return XIntc_Connect (&sys_intc, intr_id, (XInterruptHandler)handler, callback);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_unregister_int_handler
|
||||
//! @desc
|
||||
//! Unregister a handler with the interrupt controller for the specified interrupt
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sys_unregister_int_handler (int_id_t intr_id)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
// Disallow playing with timer interrupt
|
||||
if (intr_id == SYSTMR_INTR_ID )
|
||||
return;
|
||||
#endif
|
||||
|
||||
XIntc_Disconnect (&sys_intc, intr_id);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_enable_interrupt
|
||||
//! @desc
|
||||
//! Enable interrupts from the specified interrupt source
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sys_enable_interrupt (int_id_t intr_id)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
// Disallow playing with timer interrupt
|
||||
if (intr_id == SYSTMR_INTR_ID )
|
||||
return;
|
||||
#endif
|
||||
XIntc_Enable (&sys_intc, intr_id);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_disable_interrupt
|
||||
//! @desc
|
||||
//! Disable interrupts from the specified interrupt source
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sys_disable_interrupt (int_id_t intr_id)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
// Disallow playing with timer interrupt
|
||||
if (intr_id == SYSTMR_INTR_ID )
|
||||
return;
|
||||
#endif
|
||||
XIntc_Disable (&sys_intc, intr_id);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_acknowledge_interrupt
|
||||
//! @desc
|
||||
//! Acknowledge interrupt from the specified interrupt source
|
||||
//! @param
|
||||
//! - intr_id is the zero based ID of the interrupt
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sys_acknowledge_interrupt (int_id_t intr_id)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
// Disallow playing with timer interrupt
|
||||
if (intr_id == SYSTMR_INTR_ID )
|
||||
return;
|
||||
#endif
|
||||
|
||||
XIntc_Acknowledge (&sys_intc, intr_id);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INTC */
|
311
lib/bsp/xilkernel/src/src/sys/mem.c
Executable file
311
lib/bsp/xilkernel/src/src/sys/mem.c
Executable file
|
@ -0,0 +1,311 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file mem.c
|
||||
//! This contains the Memory allocation routines.
|
||||
//! - All the memory initialization routines for various system modules is
|
||||
//! defined here. The memory for all the modules are allocated statically,
|
||||
//! the size of which can be configured by the user. This can be specified
|
||||
//! in structures defined in sys/init.c. Based on this the total memory
|
||||
//! requirements for each module is calculated.
|
||||
//! - This also contains routines that allocate thread context and
|
||||
//! buffer management.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/init.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/kmsg.h>
|
||||
#include <sys/kpthread.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/bufmalloc.h>
|
||||
#include <errno.h>
|
||||
|
||||
//! Memory allocated for storing Process IDs. This memory is used for Ready
|
||||
//! Queue and Semaphore Queue. The memory is split as follows:
|
||||
//! -# Memory for Ready Queue's.
|
||||
//! -# Memory for Semaphore Queue's.
|
||||
pid_t pid_queue_mem[PID_QUEUE_MSIZE] ;
|
||||
extern process_struct ptable[MAX_PROCESS_CONTEXTS] ;
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
//! Total Memory allocated for thread context. This depends on the number of
|
||||
//! threads in the system and size of the thread context. This is user
|
||||
//! customizable.
|
||||
|
||||
char thread_stack_mem[PTHREAD_STACK_MSIZE] ;
|
||||
|
||||
//! Array of table used to keep track of Memory ID for the allocated thread
|
||||
//! context.
|
||||
//! 0 - unallocated
|
||||
//! 1 - allocated
|
||||
|
||||
char thread_stack_memid[MAX_PTHREADS] ;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
pid_t pthread_mutex_queue_mem[PTHREAD_MUTEX_QUEUE_MSIZE];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
//! Memory allocated for storing Message pointers in Message Queues.
|
||||
//! The total memory is user customizable.
|
||||
//! Each msg_t structure contains a pointer to the actual message and the size of the message
|
||||
#define MSG_QUEUE_MSIZE (NUM_MSGQS * MSGQ_CAPACITY * sizeof(msg_t))
|
||||
char msg_queue_mem[MSG_QUEUE_MSIZE] ;
|
||||
extern msgid_ds msgq_heap[] ;
|
||||
#endif /* CONFIG_MSGQ */
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
|
||||
//! Memory allocated for Shared Memory modules. The total memory is user
|
||||
//! customizable.
|
||||
|
||||
char shm_mem[SHM_MSIZE] ;
|
||||
extern struct _shm_init shm_config[] ;
|
||||
extern shm_info_t shm_heap[] ;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
membuf_t smbufs[N_STATIC_BUFS];
|
||||
//! Total memory allocated for buffer management. The memory is divided among
|
||||
//! different memory sized blocks based on the user configuration.
|
||||
char bufmallocmem[BUFMALLOC_MSIZE] ;
|
||||
extern struct bufmalloc_init_s bufmalloc_cfg[];
|
||||
#endif /* CONFIG_BUFMALLOC */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - alloc_pidq_mem
|
||||
//! @desc
|
||||
//! Allocate memory to the process ID queue's.
|
||||
//! - This includes the Ready_Q and Semaphore_Q. Initial memory is allocated
|
||||
//! for Ready queue, followed by the semaphore queue.
|
||||
//! @param
|
||||
//! - queue is the queue of PIDs
|
||||
//! - qtype is the queue type. Can be READY_Q or SEMA_Q
|
||||
//! - qno is the Queue number. (eg) There are N_PRIO number of
|
||||
//! Ready Queue. The qno denotes this number. Memory for
|
||||
//! queues is allocated sequentially.
|
||||
//! @return
|
||||
//! - None
|
||||
//! @note
|
||||
//! - SEMA_Q is valid only if CONFIG_SEMA is defined.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void alloc_pidq_mem (queuep queue, unsigned int qtype, unsigned int qno)
|
||||
{
|
||||
if (qtype == READY_Q) {
|
||||
queue->items = pid_queue_mem + (qno * MAX_READYQ * sizeof (pid_t)) ;
|
||||
}
|
||||
#ifdef CONFIG_SEMA
|
||||
else if (qtype == SEM_Q) {
|
||||
queue->items = (pid_queue_mem + SEMQ_START) + (qno * MAX_SEM_WAITQ * sizeof (pid_t));
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
else if (qtype == PTHREAD_MUTEX_Q) {
|
||||
queue->items = pthread_mutex_queue_mem + (qno * MAX_PTHREAD_MUTEX_WAITQ * sizeof (pid_t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - alloc_msgq_mem
|
||||
//! @desc
|
||||
//! Allocate memory to the Message Queues from statically allocated memory pool.
|
||||
//! @param
|
||||
//! - queue is the queue of PIDs
|
||||
//! - qno is the Queue number.
|
||||
//! @return
|
||||
//! - None
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void alloc_msgq_mem( queuep queue, unsigned int qno )
|
||||
{
|
||||
// It is always called in Sequence during system initialization !!
|
||||
static unsigned int msgq_start_ptr = 0 ;
|
||||
|
||||
queue->items = (msg_queue_mem + msgq_start_ptr) ;
|
||||
msgq_start_ptr += (sizeof(msg_t) * MSGQ_CAPACITY);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - msgq_init
|
||||
//! @desc
|
||||
//! The message Queue structures are initialized.
|
||||
//! - Based on the system configuration the message queues are created and
|
||||
//! defaults assigned to them.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void msgq_init(void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
for( ; i < NUM_MSGQS; i++ ){
|
||||
msgq_heap[i].msgid = -1;
|
||||
msgq_heap[i].msgq_len = MSGQ_CAPACITY;
|
||||
msgq_heap[i].stats.msg_qbytes = MSGQ_MAX_BYTES;
|
||||
msgq_heap[i].stats.msg_lspid = -1;
|
||||
msgq_heap[i].stats.msg_lrpid = -1;
|
||||
// Allocate space in the queue to contain msgq_len number of pointers
|
||||
alloc_q (&msgq_heap[i].msg_q, MSGQ_CAPACITY, MSG_Q, sizeof(msg_t),i);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_MSGQ */
|
||||
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - shm_init
|
||||
//! @desc
|
||||
//! The shared memory structures are initialized based on the system configuration.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void shm_init(void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
unsigned int offset = 0 ;
|
||||
|
||||
for( ; i < N_SHM; i++ ) {
|
||||
shm_heap[i].shm_id = -1;
|
||||
shm_heap[i].shm_segsz = shm_config[i].shm_size ;
|
||||
shm_heap[i].shm_addr = (char *)(shm_mem+ offset) ;
|
||||
offset += shm_config[i].shm_size;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SHM */
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - bss_mem_init
|
||||
//! @desc
|
||||
//! Initialize the bss memory allocation array. Used for thread stack allocation
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - Included only if pthread support is required
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void bss_mem_init (void)
|
||||
{
|
||||
unsigned int i ;
|
||||
for(i = 0; i < MAX_PTHREADS; i++)
|
||||
thread_stack_memid[i] = 0 ;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - alloc_bss_mem
|
||||
//! @desc
|
||||
//! Allocate memory for the bss memory, from the memory pool.
|
||||
//! @param
|
||||
//! - start is the start address of the bss memory
|
||||
//! - end is the end address of the bss memory
|
||||
//! @return
|
||||
//! - On Success, start and end are assigned the start and end address of
|
||||
//! bss memory respectively. Mem ID is returned.
|
||||
//! - -1 on Error
|
||||
//! @note
|
||||
//! - Included only if pthread support is required
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int alloc_bss_mem (unsigned int *start, unsigned int *end)
|
||||
{
|
||||
unsigned int i ;
|
||||
|
||||
for(i = 0; i < MAX_PTHREADS; i++ ){
|
||||
if( thread_stack_memid[i] == 0 ){
|
||||
/* Need to align along the boundary */
|
||||
*start = (unsigned int)thread_stack_mem + (PTHREAD_STACK_SIZE*i) ;
|
||||
*end = (*start + PTHREAD_STACK_SIZE) ;
|
||||
thread_stack_memid[i] = 1 ;
|
||||
return i ;
|
||||
}
|
||||
}
|
||||
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - free_bss_mem
|
||||
//! @desc
|
||||
//! Free the bss memory allocated for the thread.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void free_bss_mem (unsigned int memid)
|
||||
{
|
||||
thread_stack_memid[memid] = 0 ;
|
||||
}
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
||||
|
||||
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - bufmalloc_mem_init
|
||||
//! @desc
|
||||
//! Create buffer memory pools for statically specified mem configurations
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void bufmalloc_mem_init (void)
|
||||
{
|
||||
int i;
|
||||
void *ptr = bufmallocmem;
|
||||
unsigned int bufsiz;
|
||||
|
||||
for (i = 0; i < N_STATIC_BUFS; i++) {
|
||||
bufsiz = bufmalloc_cfg[i].bsiz * bufmalloc_cfg[i].nblks;
|
||||
if (sys_bufcreate (&smbufs[i], ptr, bufmalloc_cfg[i].nblks, bufmalloc_cfg[i].bsiz) != 0) {
|
||||
DBG_PRINT ("XMK: Error while initializing statically allocated block memory resources.\r\n");
|
||||
return;
|
||||
}
|
||||
ptr = ptr + bufsiz;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BUFMALLOC */
|
467
lib/bsp/xilkernel/src/src/sys/process.c
Executable file
467
lib/bsp/xilkernel/src/src/sys/process.c
Executable file
|
@ -0,0 +1,467 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file process.c
|
||||
//! This contains process management and thread management modules.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/init.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/stats.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/timer.h>
|
||||
#include <pthread.h>
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
#include <sys/kpthread.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
process_struct ptable[MAX_PROCESS_CONTEXTS]; //! Process Table
|
||||
void *kernel_sp; //! Kernel Stack pointer
|
||||
pid_t current_pid = -1; //! Currently executing processes' ID
|
||||
pid_t prev_pid = -1; //! ID of process executing immediately before a context switch
|
||||
process_struct *current_process = NULL;
|
||||
process_struct *ctx_save_process = NULL;
|
||||
pid_t idle_task_pid = 0;
|
||||
reent_t reent;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
extern unsigned int budget_ticks;
|
||||
extern signed char resched;
|
||||
extern unsigned int kernel_ticks;
|
||||
extern signed char sched_history[SCHED_HISTORY_SIZ];
|
||||
extern int shp;
|
||||
void idle_task( void ); // Idle task prototype
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - idle_task
|
||||
//! @desc
|
||||
//! - This task is run when the system is idle. This task is initialized
|
||||
//! during system init and is always run with the least priority.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void idle_task (void)
|
||||
{
|
||||
unsigned int i ;
|
||||
while (1) {
|
||||
DBG_PRINT ("Idle Task \r\n");
|
||||
for (i=0; i < 0x2fffff; i++)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - proc_create
|
||||
//! @desc
|
||||
//! Process creation primitive.
|
||||
//! - Reserves a pid for the process.
|
||||
//! - Initializes the process structure (except for the context)
|
||||
//! - Places the process in the READY_Q.
|
||||
//! @param
|
||||
//! - priority is the priority of the process
|
||||
//! @return
|
||||
//! - PID of the new process.
|
||||
//! - -1 on Error. Max. process exceeded.
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
pid_t proc_create (unsigned int priority)
|
||||
{
|
||||
unsigned char i ;
|
||||
process_struct *pcb ;
|
||||
|
||||
pcb = ptable ;
|
||||
for (i=0; i<MAX_PROCESS_CONTEXTS; i++){
|
||||
if (!pcb->is_allocated) { // Get the first unallocated PCB for the process
|
||||
pcb->is_allocated = 1;
|
||||
pcb->pid = (pid_t)i;
|
||||
pcb->state = PROC_NEW;
|
||||
pcb->priority = priority;
|
||||
pcb->blockq = NULL;
|
||||
// pcb->reent.errno = 0; // POSIX says no one sets errno to 0
|
||||
bzero ((void*)&pcb->pcontext, sizeof (process_context));
|
||||
#ifdef CONFIG_STATS
|
||||
pcb->active_ticks = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
pcb->thread = NULL; // No thread associated with this process context currently.
|
||||
#endif
|
||||
|
||||
if (pcb->pid != 0) { // Do not enqueue the idle_task
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
penq (&ready_q[0], i, 0);
|
||||
#else /* SCHED_TYPE == SCHED_PRIO */
|
||||
penq (&ready_q[priority], i, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
pcb++ ;
|
||||
}
|
||||
|
||||
if (i == MAX_PROCESS_CONTEXTS)
|
||||
return -1 ;
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
resched = 1; // Indicate rescheduling required
|
||||
#endif
|
||||
return (pid_t) (i);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_kill
|
||||
//! @desc
|
||||
//! Removes the process with pid from the system. No indication is given to other processes that
|
||||
//! depend on this process.
|
||||
//! @param
|
||||
//! - pid is the process ID of process to kill
|
||||
//! @return
|
||||
//! - 0 on Success
|
||||
//! - -1 on Error
|
||||
//! @note
|
||||
//! - Included only if CONFIG_KILL is defined (os_config.h) or if hardware exceptions are
|
||||
//! supported on the given processor
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#if defined(CONFIG_KILL) || defined(CONFIG_HARDWARE_EXCEPTIONS)
|
||||
int sys_kill (pid_t pid)
|
||||
{
|
||||
if ((ptable[pid].is_allocated == 0))
|
||||
return -1;
|
||||
|
||||
if (pid == current_pid) {
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
if (ptable[pid].thread)
|
||||
sys_pthread_exit (NULL);
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
else
|
||||
sys_elf_exit ();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Control does not reach here
|
||||
}
|
||||
|
||||
if (ptable[pid].state == PROC_READY) {
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
pdelq (&ready_q[0], pid);
|
||||
#elif SCHED_TYPE == SCHED_PRIO
|
||||
pdelq (&ready_q[ptable[pid].priority], pid);
|
||||
#endif
|
||||
} else if (ptable[pid].state == PROC_WAIT || ptable[pid].state == PROC_TIMED_WAIT) {
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
pdelq (ptable[pid].blockq, pid);
|
||||
#elif SCHED_TYPE == SCHED_PRIO
|
||||
prio_pdelq (ptable[pid].blockq, pid);
|
||||
#endif
|
||||
#ifdef CONFIG_TIME
|
||||
if (ptable[pid].state == PROC_TIMED_WAIT)
|
||||
remove_tmr (pid);
|
||||
} else if (ptable[pid].state == PROC_DELAY)
|
||||
remove_tmr (pid);
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
if (ptable[pid].thread)
|
||||
pthread_terminate (ptable[pid].thread);
|
||||
else
|
||||
#endif
|
||||
process_invalidate(&ptable[pid]);
|
||||
|
||||
resched = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_KILL */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - process_invalidate
|
||||
//! @desc
|
||||
//! Remove the Process with pid.
|
||||
//! This is an internal proc that is called by
|
||||
//! sys_kill() and also by the schedulers to remove "DEAD" processes
|
||||
//! @param
|
||||
//! - proc is the process structure of process to invalidate
|
||||
//! @return
|
||||
//! - 0 on Success
|
||||
//! - -1 on Error
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int process_invalidate (process_struct *proc)
|
||||
{
|
||||
#ifdef CONFIG_STATS
|
||||
budget_ticks++;
|
||||
#endif
|
||||
proc->is_allocated = 0 ;
|
||||
proc->state = PROC_DEAD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_process_status
|
||||
//! @desc
|
||||
//! Return the status of the process.
|
||||
//! @param
|
||||
//! - pid is the Process ID of the process.
|
||||
//! - ps is the structure where the status is returned.
|
||||
//! @return
|
||||
//! - The status of the process is returned on ps
|
||||
//! - If pid not an active process, ps->pid is assigned -1
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_process_status (pid_t pid, p_stat *ps)
|
||||
{
|
||||
if (ptable[pid].is_allocated) {
|
||||
ps->pid = pid;
|
||||
ps->state = ptable[pid].state ;
|
||||
} else {
|
||||
ps->pid = -1;
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_yield
|
||||
//! @desc
|
||||
//! Yield the processor to the next process.
|
||||
//! - The current process changes to READY state and is enqueued in the
|
||||
//! ready queue.
|
||||
//! @return
|
||||
//! - None
|
||||
//! @note
|
||||
//! - Included only if CONFIG_YIELD is defined. (os_config.h)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifdef CONFIG_YIELD
|
||||
int sys_yield(void)
|
||||
{
|
||||
resched = 1;
|
||||
return 0 ;
|
||||
}
|
||||
#endif /* CONFIG_YIELD */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_get_currentPID
|
||||
//! @desc
|
||||
//! Return the PID of the currently running process context
|
||||
//! @return
|
||||
//! - PID of the currently running process context.
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
pid_t sys_get_currentPID (void)
|
||||
{
|
||||
return current_pid ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - process_block
|
||||
//! @desc
|
||||
//! Block the process.
|
||||
//! - Place the process into the specified wait queue, change the state of the process and
|
||||
//! set the kernel flag to PROCESS_BLOCK.
|
||||
//! - Call the process_scheduler
|
||||
//! @param
|
||||
//! - queue is the queue where the process is enqueued.
|
||||
//! - state is the state of the process in queue.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void process_block (queuep queue, unsigned int state)
|
||||
{
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
penq (queue, current_pid, 0);
|
||||
#else
|
||||
prio_penq (queue, current_pid, 0);
|
||||
#endif
|
||||
current_process->blockq = queue;
|
||||
current_process->state = state;
|
||||
suspend ();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - process_unblock
|
||||
//! @desc
|
||||
//! Unblock the first process in queue and place it onto the ready queue.
|
||||
//! Call the process_scheduler only if this is PRIO scheduling. This is because we do not want the
|
||||
//! current process to prematurely lose its time slice. Change the state of the process to
|
||||
//! PROC_READY
|
||||
//! @param
|
||||
//! - queue is the queue where the process is enqueued.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void process_unblock (queuep queue)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
pdeq (queue, &pid, 0);
|
||||
#else
|
||||
prio_pdeq (queue, &pid, 0);
|
||||
#endif
|
||||
|
||||
if (pid == -1)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
if (ptable[pid].state == PROC_TIMED_WAIT) // This process is also on a list of timers. Remove it.
|
||||
ptable[pid].remain = remove_tmr (pid);
|
||||
|
||||
#endif
|
||||
|
||||
ptable[pid].state = PROC_READY;
|
||||
ptable[pid].blockq = NULL;
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
penq (&ready_q[0], pid, 0);
|
||||
#else /* SCHED_TYPE == SCHED_PRIO */
|
||||
penq (&ready_q[ptable[pid].priority], pid, 0);
|
||||
resched = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void proc_restore_state (void)
|
||||
{
|
||||
reent._errno = current_process->reent._errno;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - get_kernel_stats
|
||||
//! @desc
|
||||
//! Retrieve statistics about executing processes, ticks, history of processes scheduled since last
|
||||
//! last call etc.
|
||||
//! @param
|
||||
//! - stats is the structure to store the statistics information in.
|
||||
//! @return
|
||||
//! - 0 on success
|
||||
//! - -1 if error
|
||||
//! - 1 if history overflowed
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_get_kernel_stats (kstats_t *stats)
|
||||
{
|
||||
int i, count, ret = 0;
|
||||
|
||||
if (stats == NULL)
|
||||
return -1;
|
||||
|
||||
if (stats->pstat_count <= 0)
|
||||
return -1;
|
||||
|
||||
count = 0;
|
||||
for (i=0; i<MAX_PROCESS_CONTEXTS; i++) {
|
||||
if (count == stats->pstat_count)
|
||||
break;
|
||||
|
||||
if (!ptable[i].is_allocated)
|
||||
continue;
|
||||
|
||||
stats->pstats[count].pid = ptable[i].pid;
|
||||
stats->pstats[count].state = ptable[i].state;
|
||||
stats->pstats[count].priority = ptable[i].priority;
|
||||
stats->pstats[count].aticks = ptable[i].active_ticks;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
stats->pstat_count = count;
|
||||
stats->kernel_ticks = budget_ticks;
|
||||
|
||||
for (i=0; i<shp; i++)
|
||||
stats->sched_history[i] = sched_history[i];
|
||||
|
||||
if (shp == SCHED_HISTORY_SIZ)
|
||||
ret = 1;
|
||||
else
|
||||
stats->sched_history[i] = -1;
|
||||
|
||||
shp = 0; // Reset history pointer
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_get_reentrancy
|
||||
//! @desc
|
||||
//! Return the kernel re-entrancy structure. This structure holds program level state
|
||||
//! information for the current process. Upon each context switch this structure is updated.
|
||||
//! to minimize the run-time efficiency, each application ELF file can query a pointer to this
|
||||
//! structure once and then use it for all subsequent state information queries.
|
||||
//! @param
|
||||
//! - None
|
||||
//! @return
|
||||
//! - Pointer to kernel re-entrancy structure
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
reent_t* sys_get_reentrancy (void)
|
||||
{
|
||||
return &reent;
|
||||
}
|
502
lib/bsp/xilkernel/src/src/sys/pthread.c
Executable file
502
lib/bsp/xilkernel/src/src/sys/pthread.c
Executable file
|
@ -0,0 +1,502 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file pthread.c
|
||||
//! The kernel pthreads implementation
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <config/config_param.h>
|
||||
#include <sys/arch.h>
|
||||
#include <sys/kpthread.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/init.h>
|
||||
#include <sys/decls.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
pthread_attr_t default_attr;
|
||||
pthread_info_t thread_info_list[MAX_PTHREADS];
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
extern process_struct ptable[MAX_PROCESS_CONTEXTS] ;
|
||||
extern process_struct *current_process;
|
||||
extern signed char current_pid;
|
||||
extern signed char resched;
|
||||
extern struct _queue ready_q[] ; // Ready Queue
|
||||
extern void setup_initial_context (process_struct *pcb, pid_t parent, unsigned int startaddr, unsigned int stackaddr, unsigned int stacksize);
|
||||
|
||||
void invalidate_thread_info (pthread_info_t *thread);
|
||||
void* pthread_wrapper (void *arg);
|
||||
pthread_info_t* pthread_get_info (pthread_t thr);
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
extern void pthread_mutex_heap_init(void);
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pthread_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
bss_mem_init ();
|
||||
default_attr.schedparam.sched_priority = PRIO_LOWEST; // Defaults to the lowest priority.
|
||||
default_attr.contentionscope = PTHREAD_SCOPE_SYSTEM; // Only system scope supported.
|
||||
default_attr.detachstate = PTHREAD_CREATE_DETACHED; // Detach on thread exit
|
||||
default_attr.stackaddr = NULL;
|
||||
default_attr.stacksize = 0;
|
||||
|
||||
for (i=0; i<MAX_PTHREADS; i++) {
|
||||
thread_info_list[i].is_allocated = 0;
|
||||
thread_info_list[i].state = PTHREAD_STATE_DETACHED;
|
||||
thread_info_list[i].join_thread = NULL;
|
||||
thread_info_list[i].tid = (pthread_t)i; // Can statically allocate thread ids.
|
||||
thread_info_list[i].mem_id = -1; // BSS memory unallocated.
|
||||
thread_info_list[i].thread_attr = default_attr;
|
||||
thread_info_list[i].parent = NULL;
|
||||
alloc_q (&thread_info_list[i].joinq,1,PTHREAD_JOIN_Q,sizeof(char),0);
|
||||
thread_info_list[i].joinq.items = &(thread_info_list[i].joinq_mem);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
pthread_mutex_heap_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void invalidate_thread_info (pthread_info_t *thread)
|
||||
{
|
||||
thread->is_allocated = 0;
|
||||
thread->join_thread = NULL;
|
||||
thread->start_func = NULL;
|
||||
thread->param = NULL;
|
||||
thread->retval = NULL;
|
||||
thread->parent = NULL;
|
||||
thread->state = PTHREAD_STATE_DETACHED;
|
||||
alloc_q (&(thread->joinq),1,PTHREAD_JOIN_Q,sizeof(char),0); // Realloc Q afresh
|
||||
qinit (&(thread->joinq));
|
||||
thread->joinq.items = &(thread->joinq_mem);
|
||||
|
||||
if( thread->mem_id != -1 ) {
|
||||
free_bss_mem (thread->mem_id) ;
|
||||
thread->mem_id = -1; // BSS memory unallocated.
|
||||
}
|
||||
|
||||
thread->thread_attr = default_attr;
|
||||
}
|
||||
|
||||
void* pthread_wrapper (void *arg)
|
||||
{
|
||||
void* status = NULL;
|
||||
pthread_t cur = sys_pthread_self ();
|
||||
pthread_info_t *self = pthread_get_info (cur);
|
||||
|
||||
arg = 0;
|
||||
status = (*(self->start_func))(self->param);
|
||||
|
||||
xmk_enter_kernel ();
|
||||
sys_pthread_exit (status); // Implicit exit at the end of the thread's execution
|
||||
xmk_leave_kernel (); // We should never get here. There will be a leave_kernel done on our behalf by newly scheduled process or kernel
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
pthread_info_t* pthread_get_info (pthread_t thr)
|
||||
{
|
||||
if ((int)thr >=0 && (int)thr < MAX_PTHREADS)
|
||||
return &thread_info_list[thr];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_create
|
||||
//! @desc
|
||||
//! Thread creation routine
|
||||
//! - Verify pthread attributes
|
||||
//! - Allocate a pthread info structure
|
||||
//! - Allocate a context (bss memory) for the new thread.
|
||||
//! - Call sys_process_create to allocate a pid.
|
||||
//! - If SCHED_PRIO, call the process_scheduler
|
||||
//! @param
|
||||
//! - thread is location where the ID of the created thread is stored.
|
||||
//! - attr is the reference to thread initialization attributes.
|
||||
//! - start_func is the address of start routine.
|
||||
//! - param is the pointer argument to the thread.
|
||||
//! @return
|
||||
//! - 0 on success and thread ID of created thread in *'thread'
|
||||
//! - EINVAL, EAGAIN on errors
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_create (pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_func)(void*), void *param)
|
||||
{
|
||||
int pid, i;
|
||||
unsigned int bss_start_addr, bss_end_addr, stackaddr, stacksize;
|
||||
pthread_info_t *cur_thread;
|
||||
|
||||
if (thread == NULL) // Should actually just throw an illegal memory access exception
|
||||
return -1; // Rather returning an undefined error code.
|
||||
|
||||
if (attr != NULL) { // Examine attr to determine validity
|
||||
if ((attr->schedparam.sched_priority > PRIO_LOWEST) // attr priority parameters out of bounds
|
||||
|| (attr->schedparam.sched_priority < PRIO_HIGHEST) // attr priority parameters out of bounds
|
||||
|| (attr->contentionscope != PTHREAD_SCOPE_SYSTEM) // Only system contention scope supported
|
||||
|| ((attr->detachstate != PTHREAD_CREATE_DETACHED)
|
||||
&& (attr->detachstate != PTHREAD_CREATE_JOINABLE))
|
||||
)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
else attr = &default_attr;
|
||||
|
||||
cur_thread = thread_info_list;
|
||||
for (i=0; i < MAX_PTHREADS; i++) {
|
||||
if (!(cur_thread->is_allocated)){ // Get the first unallocated
|
||||
cur_thread->is_allocated = 1 ; // Thread info structure for this thread
|
||||
cur_thread->state = PTHREAD_STATE_ALIVE;
|
||||
cur_thread->start_func = start_func;
|
||||
cur_thread->param = param;
|
||||
cur_thread->join_thread = NULL;
|
||||
cur_thread->thread_attr = *attr;
|
||||
qinit (&(cur_thread->joinq));
|
||||
break;
|
||||
}
|
||||
cur_thread++;
|
||||
}
|
||||
|
||||
if (i == MAX_PTHREADS) // No more resources to create new threads.
|
||||
return EAGAIN;
|
||||
|
||||
if (attr->stackaddr == NULL) { // Allocate a stack from our BSS pool only if no stack has been specified in attr
|
||||
cur_thread->mem_id = alloc_bss_mem (&bss_start_addr, &bss_end_addr);
|
||||
if (cur_thread->mem_id == -1) {
|
||||
invalidate_thread_info (cur_thread);
|
||||
return EAGAIN ;
|
||||
}
|
||||
}
|
||||
|
||||
pid = proc_create (attr->schedparam.sched_priority);
|
||||
if( pid == -1 ) {
|
||||
invalidate_thread_info (cur_thread); // No more resources to create new threads.
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
if (attr->stackaddr == NULL) {
|
||||
stackaddr = (bss_end_addr + SSTACK_PTR_ADJUST);
|
||||
stacksize = PTHREAD_STACK_SIZE;
|
||||
}
|
||||
else {
|
||||
stackaddr = (unsigned int)(attr->stackaddr + attr->stacksize + SSTACK_PTR_ADJUST);
|
||||
stacksize = attr->stacksize;
|
||||
}
|
||||
|
||||
setup_initial_context (&ptable[pid], current_pid, (unsigned int)pthread_wrapper, stackaddr, stacksize);
|
||||
|
||||
ptable[pid].thread = cur_thread;
|
||||
cur_thread->parent = &ptable[pid];
|
||||
*thread = cur_thread->tid;
|
||||
|
||||
#ifdef CONFIG_DEBUGMON
|
||||
cur_thread->thread_attr.stackaddr = (void*)stackaddr;
|
||||
cur_thread->thread_attr.stacksize = stacksize;
|
||||
#endif
|
||||
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_exit
|
||||
//! @desc
|
||||
//! Thread termination routine.
|
||||
//! - Store retval for reclamation by other threads. Set thread state.
|
||||
//! - If thread waiting to join, then unblock that thread and terminate.
|
||||
//! - If detachstate is set, then detach self.
|
||||
//! - Block and terminate.
|
||||
//! @param
|
||||
//! - retval is the value returned by thread's main routine
|
||||
//! @return
|
||||
//! - Does not return
|
||||
//! @note
|
||||
//! - Irrespective of whether detachstate is PTHREAD_CREATE_DETACHED or not, thread waiting to join
|
||||
//! is unblocked.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sys_pthread_exit (void *retval)
|
||||
{
|
||||
pthread_info_t *self = current_process->thread;
|
||||
|
||||
self->retval = retval; // Store the retval for use by joining threads
|
||||
self->state = PTHREAD_STATE_EXIT;
|
||||
|
||||
if (self->join_thread != NULL)
|
||||
process_unblock (&self->joinq); // Unblock the thread that is waiting to join with self.
|
||||
|
||||
if (self->thread_attr.detachstate == PTHREAD_CREATE_DETACHED) {
|
||||
process_invalidate (self->parent);
|
||||
invalidate_thread_info (self);
|
||||
}
|
||||
else current_process->state = PROC_DEAD;
|
||||
|
||||
suspend ();
|
||||
}
|
||||
|
||||
void pthread_terminate (pthread_info_t *thread)
|
||||
{
|
||||
thread->retval = NULL; // Store the retval for use by joining threads
|
||||
thread->state = PTHREAD_STATE_EXIT;
|
||||
|
||||
if (thread->join_thread != NULL)
|
||||
process_unblock (&thread->joinq); // Unblock the thread that is waiting to join with self.
|
||||
|
||||
if (thread->thread_attr.detachstate == PTHREAD_CREATE_DETACHED) {
|
||||
process_invalidate (thread->parent);
|
||||
invalidate_thread_info (thread);
|
||||
}
|
||||
else thread->parent->state = PROC_DEAD;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_join
|
||||
//! @desc
|
||||
//! Suspend current thread till target thread terminates. Then completely detach target thread.
|
||||
//! - Verify target is present and is joinable
|
||||
//! - Block onto target's join queue
|
||||
//! - When unblocked, if thread not already detached, detach it
|
||||
//! - if retval is not NULL, then store target's return value in *retval.
|
||||
//! @param
|
||||
//! - target is the thread to join with
|
||||
//! - retval is the location to store return value of target thread.
|
||||
//! @return
|
||||
//! - Return 0 on success and return value of target thread in location referenced by retval.
|
||||
//! - Return ESRCH, EINVAL as appropriate
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_join (pthread_t target, void **retval)
|
||||
{
|
||||
pthread_info_t *target_info = pthread_get_info (target);
|
||||
pthread_t cur = sys_pthread_self ();
|
||||
pthread_info_t *self = pthread_get_info (cur);
|
||||
|
||||
if (target_info == NULL)
|
||||
return ESRCH;
|
||||
|
||||
// @note - Can possibly detect deadlocks here
|
||||
if (target_info->state == PTHREAD_STATE_ALIVE) {
|
||||
if (target_info->join_thread != NULL) // Some other thread already waiting to join
|
||||
return EINVAL; // Therefore invalid to join with this target
|
||||
|
||||
target_info->join_thread = self; // Block and yield execution to some other context
|
||||
process_block (&(target_info->joinq), PROC_WAIT); // Indicate that self wants to join with target.
|
||||
|
||||
if (retval != NULL)
|
||||
*retval = target_info->retval;
|
||||
} else if (target_info->state == PTHREAD_STATE_DETACHED) // Can potentially return success here.
|
||||
return ESRCH; // POSIX is not specific about behavior on multiple joins to an already terminated thread.
|
||||
|
||||
if (target_info->state != PTHREAD_STATE_DETACHED) { // Target thread already in state PTHREAD_STATE_EXIT. Detach target thread.
|
||||
if (retval != NULL) // Thread already detached if detachstate was PTHREAD_STATE_DETACHED,
|
||||
*retval = target_info->retval;
|
||||
process_invalidate (target_info->parent); // Clear up corresponding parent structure
|
||||
invalidate_thread_info (target_info);
|
||||
}
|
||||
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_self
|
||||
//! @desc
|
||||
//! Get handle to self
|
||||
//! @param
|
||||
//! - none
|
||||
//! @return
|
||||
//! - return pthread_t tid of current thread
|
||||
//! - -1 on error
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
pthread_t sys_pthread_self (void)
|
||||
{
|
||||
if (current_pid == -1)
|
||||
return (pthread_t)-1;
|
||||
return (pthread_t)current_process->thread->tid;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_detach
|
||||
//! @desc
|
||||
//! Change detachstate of target thread to PTHREAD_CREATE_DETACHED
|
||||
//! - If thread already terminated, then detach target, else change detachstate
|
||||
//! @param
|
||||
//! - thread is the target thread
|
||||
//! @return
|
||||
//! - Return 0 on success
|
||||
//! - ESRCH if target not found.
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_detach (pthread_t thread)
|
||||
{
|
||||
pthread_info_t *thread_info;
|
||||
thread_info = pthread_get_info (thread);
|
||||
|
||||
if (thread_info == NULL)
|
||||
return ESRCH;
|
||||
|
||||
if (thread_info->state == PTHREAD_STATE_EXIT) {
|
||||
process_invalidate (thread_info->parent);
|
||||
invalidate_thread_info (thread_info);
|
||||
}
|
||||
else
|
||||
thread_info->thread_attr.detachstate = PTHREAD_STATE_DETACHED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_equal
|
||||
//! @desc
|
||||
//! Compare two pthread_t structures
|
||||
//! @param
|
||||
//! - thread_1 and thread_2 are the thread ID structures of the two threads
|
||||
//! @return
|
||||
//! - Return 1 if equal, elze 0
|
||||
//! @note
|
||||
//! - none
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_equal (pthread_t thread_1, pthread_t thread_2)
|
||||
{
|
||||
if ((pthread_get_info (thread_1) == pthread_get_info (thread_2)))
|
||||
return 1;
|
||||
return 0; // Else
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_getschedparam
|
||||
//! @desc
|
||||
//! Form and return a sched_param structure of the thread identified by 'thread'
|
||||
//! @param
|
||||
//! - thread is the identifier of the target thread
|
||||
//! - policy is a pointer to the structure where the current scheduling policy for this thread is saved
|
||||
//! - param is the sched_param structure to store the schedule attributes in
|
||||
//! @return
|
||||
//! - Return 0 on success
|
||||
//! - Return ESRCH if target thread not found
|
||||
//! - Return EINVAL if param/policy point to invalid structures
|
||||
//! @note
|
||||
//! - Currently sched_param contains only priority
|
||||
//! - The policy returned indicates the global scheduling policy (there is no per thread policy)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param)
|
||||
{
|
||||
pthread_info_t *thread_info;
|
||||
thread_info = pthread_get_info (thread);
|
||||
|
||||
if (thread_info == NULL)
|
||||
return ESRCH;
|
||||
|
||||
if ((param == NULL || policy == NULL))
|
||||
return EINVAL;
|
||||
|
||||
param->sched_priority = thread_info->parent->priority;
|
||||
*policy = SCHED_PRIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_pthread_setschedparam
|
||||
//! @desc
|
||||
//! Change the scheduling parameters of the thread identified by 'thread'
|
||||
//! @param
|
||||
//! - thread is the identifier of the target thread
|
||||
//! - policy is the target's new required scheduling policy
|
||||
//! - param is the target's new required scheduling parameters
|
||||
//! @return
|
||||
//! - Return 0 on success
|
||||
//! - Return ESRCH if target thread not found
|
||||
//! - Return EINVAL if scheduling parameters are invalid
|
||||
//! - Return -1 on unhandled errors
|
||||
//! @note
|
||||
//! - policy is ignored
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int sys_pthread_setschedparam (pthread_t thread, int policy, struct sched_param *param)
|
||||
{
|
||||
pthread_info_t *thread_info;
|
||||
thread_info = pthread_get_info (thread);
|
||||
|
||||
if (thread_info == NULL)
|
||||
return ESRCH;
|
||||
|
||||
if ((param->sched_priority > PRIO_LOWEST) // Check requested priority change
|
||||
|| (param->sched_priority < PRIO_HIGHEST))
|
||||
return EINVAL;
|
||||
|
||||
if (thread_info->parent->pid == current_pid ||
|
||||
thread_info->parent->state == PROC_DELAY) { // Just need to change the priority
|
||||
thread_info->parent->priority = param->sched_priority;
|
||||
} else if (thread_info->parent->state == PROC_READY) { // cannot handle processes which are blocked
|
||||
if (pdelq (&ready_q[thread_info->parent->priority],
|
||||
thread_info->parent->pid) < 0) // Remove from corresponding priority queue
|
||||
return -1;
|
||||
thread_info->parent->priority = param->sched_priority; // Change priority and enqueue in new queue
|
||||
penq (&ready_q[thread_info->parent->priority], thread_info->parent->pid, 0);
|
||||
} else if (thread_info->parent->state == PROC_WAIT ||
|
||||
thread_info->parent->state == PROC_TIMED_WAIT) { // Thread currently blocked
|
||||
if (prio_pdelq (thread_info->parent->blockq, // Remove from corresponding wait queue
|
||||
thread_info->parent->pid) < 0)
|
||||
return -1;
|
||||
thread_info->parent->priority = param->sched_priority; // Change priority and enqueue in new queue
|
||||
prio_penq (thread_info->parent->blockq, thread_info->parent->pid, 0);
|
||||
}
|
||||
|
||||
resched = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* SCHED_TYPE == SCHED_PRIO */
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
404
lib/bsp/xilkernel/src/src/sys/queue.c
Executable file
404
lib/bsp/xilkernel/src/src/sys/queue.c
Executable file
|
@ -0,0 +1,404 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file queue.c
|
||||
//! This file contains the Queue Handling routines.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <os_config.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mem.h>
|
||||
#include <sys/process.h>
|
||||
|
||||
#define LEFT_CHILD(index) ((index << 1) + 1)
|
||||
#define RIGHT_CHILD(index) ((index << 1) + 2)
|
||||
#define PARENT(index) ((int)((index - 1) >> 1))
|
||||
#define PROC_PRIO(index) (ptable[index].priority)
|
||||
|
||||
extern process_struct ptable[MAX_PROCESS_CONTEXTS];
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func alloc_q
|
||||
//! @desc
|
||||
//! Initialize a Queue - Allocate array of memory to the Queue. Called
|
||||
//! during system initialization.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - max_items is the maximum queue length.
|
||||
//! - size is size of the elements in the queue.
|
||||
//! - qtype is the type of Q. Each Q is allocated a static memory
|
||||
//! - qno is the queue number, In case of multiple queue's of
|
||||
//! the same type.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void alloc_q (queuep queue, unsigned char max_items,
|
||||
unsigned char qtype, unsigned short size, unsigned char qno)
|
||||
{
|
||||
queue->item_count = queue->qfront = queue->qend = 0;
|
||||
queue->max_items = max_items;
|
||||
queue->item_size = size;
|
||||
if (qtype != MSG_Q)
|
||||
alloc_pidq_mem (queue, qtype, qno);
|
||||
#ifdef CONFIG_MSGQ
|
||||
else
|
||||
alloc_msgq_mem (queue, qno);
|
||||
#endif
|
||||
// Check for NULL
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - qinit
|
||||
//! @desc
|
||||
//! Intialize the Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void qinit (queuep queue)
|
||||
{
|
||||
queue->item_count = queue->qfront = queue->qend = 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - enq
|
||||
//! @desc
|
||||
//! enqueue the item in the Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is the queue element.
|
||||
//! - key for insertion into the Queue. Can be priority.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - key is not used currently
|
||||
//! - No error is flagged if queue is full
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void enq (queuep queue, const void *item, unsigned short key)
|
||||
{
|
||||
unsigned char qend = queue->qend;
|
||||
|
||||
key = 0;
|
||||
// Queue full
|
||||
if (queue->item_count == queue->max_items) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy ((queue->items+(qend*queue->item_size)),item,queue->item_size);
|
||||
queue->qend = (qend+1) % (queue->max_items);
|
||||
queue->item_count++;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - deq
|
||||
//! @desc
|
||||
//! Dequeue the process from the Queue, based on the schemes.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is buffer where queue element is returned.
|
||||
//! If queue is empty then NULL is returned.
|
||||
//! - key for removing from the Queue.
|
||||
//! @return
|
||||
//! - Queue element is returned in item.
|
||||
//! - Null is assigned to item if Error.
|
||||
//! @note
|
||||
//! - No error is flagged on queue being empty
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void deq (queuep queue, void *item, unsigned short key)
|
||||
{
|
||||
unsigned char qfront = queue->qfront ;
|
||||
|
||||
key = 0;
|
||||
// Queue EMPTY
|
||||
if (queue->item_count == 0) {
|
||||
item = NULL ;
|
||||
return ;
|
||||
}
|
||||
|
||||
memcpy (item,(queue->items+(qfront*queue->item_size)),queue->item_size);
|
||||
queue->qfront = (qfront+1)%(queue->max_items);
|
||||
queue->item_count--;
|
||||
return ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - penq
|
||||
//! @desc
|
||||
//! Enqueue a process id in the Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is the queue element.
|
||||
//! - key for insertion into the Queue. Can be priority.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - key is not used currently
|
||||
//! - No error is flagged if queue is full.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void penq (queuep queue, pid_t item, unsigned short key)
|
||||
{
|
||||
unsigned char qend = queue->qend ;
|
||||
pid_t* citems = (pid_t*)(queue->items);
|
||||
|
||||
key = 0;
|
||||
// Queue full
|
||||
if (queue->item_count == queue->max_items) {
|
||||
return ;
|
||||
}
|
||||
|
||||
citems[qend] = item;
|
||||
queue->qend = (qend + 1) % (queue->max_items) ;
|
||||
queue->item_count++;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pdeq
|
||||
//! @desc
|
||||
//! Dequeue the process from the Queue, based on the schemes.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is buffer where queue element is returned.
|
||||
//! If queue is empty then 255 is returned.
|
||||
//! - key for removing from the Queue.
|
||||
//! @return
|
||||
//! - Queue element is returned in item.
|
||||
//! - 255 (-1) is assigned to item if Error.
|
||||
//! @note
|
||||
//! - No error is flagged if queue is empty
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void pdeq (queuep queue, pid_t *item, unsigned short key)
|
||||
{
|
||||
unsigned char qfront = queue->qfront ;
|
||||
pid_t *citems = (pid_t*) (queue->items);
|
||||
|
||||
key = 0;
|
||||
// Queue EMPTY
|
||||
if (queue->item_count == 0) {
|
||||
*item = 255;
|
||||
return ;
|
||||
}
|
||||
*item = citems[qfront];
|
||||
queue->qfront = (qfront + 1) % (queue->max_items);
|
||||
queue->item_count--;
|
||||
return ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - pdelq
|
||||
//! @desc
|
||||
//! Delete a pid from the Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is the element to delete.
|
||||
//! If queue is empty then -1 is returned.
|
||||
//! @return
|
||||
//! - Return 0 on success and -1 on errors
|
||||
//! @note
|
||||
//! - Since the Queue implementation is array, this operation is very
|
||||
//! expensive as other entries needs to be copied.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int pdelq (queuep queue, pid_t item)
|
||||
{
|
||||
unsigned char qfront = queue->qfront;
|
||||
unsigned char qend = queue->qend;
|
||||
unsigned char item_count = queue->item_count;
|
||||
unsigned char max_items = queue->max_items;
|
||||
pid_t *citems = (pid_t*) (queue->items);
|
||||
|
||||
if (item_count == 0)
|
||||
return -1; /* Queue EMPTY */
|
||||
|
||||
while ((item_count) && (item != citems[qfront])) {
|
||||
item_count--;
|
||||
qfront = (qfront + 1) % max_items ;
|
||||
}
|
||||
|
||||
if (!item_count)
|
||||
return -1;
|
||||
|
||||
if (qfront == queue->qfront)
|
||||
queue->qfront = (qfront + 1) % max_items;
|
||||
else {
|
||||
unsigned int temp = qfront;
|
||||
while (qfront != qend) {
|
||||
qfront = (qfront + 1) % max_items;
|
||||
citems[temp] = citems[qfront];
|
||||
temp = qfront;
|
||||
}
|
||||
queue->qend = (qend + max_items - 1) % max_items ;
|
||||
}
|
||||
queue->item_count--;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - prio_penq
|
||||
//! @desc
|
||||
//! Enqueue a process in the Priority Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is the queue element.
|
||||
//! - Key for insertion (priority).
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - No error is flagged if queue is full.
|
||||
//! - Uses queue array structure as a binary heap for implementing priority queue.
|
||||
//! 0 is highest priority
|
||||
//! - The priority key is not used. Instead the value is obtained directly from the ptable.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void prio_penq (queuep queue, pid_t item, unsigned short key)
|
||||
{
|
||||
pid_t* citems = (pid_t*)(queue->items);
|
||||
unsigned char tmp, cur;
|
||||
|
||||
if (queue->item_count == queue->max_items)
|
||||
return;
|
||||
|
||||
citems[queue->qend] = item; // qend points to the next free space in the queue
|
||||
|
||||
cur = queue->qend; // Propagate new value up the heap
|
||||
while (cur != 0) {
|
||||
if (PROC_PRIO (citems[PARENT (cur)]) > PROC_PRIO (citems[cur])) {
|
||||
tmp = citems[cur];
|
||||
citems[cur] = citems[PARENT (cur)]; // Swap
|
||||
citems[PARENT (cur)] = tmp;
|
||||
}
|
||||
else break;
|
||||
cur = PARENT (cur);
|
||||
}
|
||||
|
||||
queue->qend++;
|
||||
queue->item_count++;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - prio_pdeq
|
||||
//! @desc
|
||||
//! Dequeue the highest priority process from the Queue.
|
||||
//! @param
|
||||
//! - queue is the queue of items.
|
||||
//! - item is buffer where queue element is returned.
|
||||
//! If queue is empty then 255 is returned.
|
||||
//! - Key for removing from the Queue (priority)
|
||||
//! @return
|
||||
//! - Queue element is returned in item.
|
||||
//! - 255 (-1) is assigned to item if Error.
|
||||
//! @note
|
||||
//! - Uses queue array structure as a binary heap for implementing priority queue.
|
||||
//! 0 is highest priority
|
||||
//! - The priority key is not used currently. Instead the value is obtained from the ptable directly.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void prio_pdeq (queuep queue, pid_t *item, unsigned short key)
|
||||
{
|
||||
pid_t *citems = (pid_t*) (queue->items);
|
||||
unsigned char tmp, cur;
|
||||
pid_t slct, ret;
|
||||
|
||||
// Queue EMPTY
|
||||
if (queue->item_count == 0) {
|
||||
*item = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = citems[0];
|
||||
// Remove head (highest prio)
|
||||
citems[0] = citems[queue->qend - 1]; // Reshape heap (Take lowest prio. Place it at head. Propagate it down the heap)
|
||||
|
||||
cur = 0;
|
||||
while (LEFT_CHILD (cur) <= (queue->qend - 1)) { // While cur has children in the heap
|
||||
if ((RIGHT_CHILD (cur) > (queue->qend - 1)) ||
|
||||
(PROC_PRIO (citems[LEFT_CHILD (cur)]) <= PROC_PRIO (citems[RIGHT_CHILD (cur)])))
|
||||
slct = LEFT_CHILD (cur);
|
||||
else
|
||||
slct = RIGHT_CHILD (cur);
|
||||
|
||||
if (PROC_PRIO (citems[slct]) <= PROC_PRIO (citems[cur])) {
|
||||
tmp = citems[cur]; // Swap
|
||||
citems[cur] = citems[slct];
|
||||
citems[slct] = tmp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
cur = slct;
|
||||
}
|
||||
|
||||
queue->qend--;
|
||||
queue->item_count--;
|
||||
*item = ret;
|
||||
}
|
||||
|
||||
int prio_pdelq (queuep queue, pid_t item)
|
||||
{
|
||||
unsigned char i;
|
||||
pid_t *citems = (pid_t*) (queue->items);
|
||||
unsigned char qsiz = queue->item_count;
|
||||
pid_t tmp;
|
||||
signed char priosave;
|
||||
|
||||
if (qsiz == 0)
|
||||
return -1; // Queue EMPTY
|
||||
|
||||
for (i = 0; i < qsiz; i++) {
|
||||
if (citems[i] == item)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == qsiz)
|
||||
return -1;
|
||||
|
||||
priosave = PROC_PRIO (citems[i]); // Found our item. Now do a "decreaseKey" heap operation on it
|
||||
PROC_PRIO (citems[i]) = -1;
|
||||
|
||||
while (i != 0) { // Propagate new value up the heap
|
||||
tmp = citems[i];
|
||||
citems[i] = citems[PARENT (i)]; // Swap
|
||||
citems[PARENT (i)] = tmp;
|
||||
i = PARENT (i);
|
||||
}
|
||||
|
||||
prio_pdeq (queue, &tmp, 0); // Now delete this element from the queue
|
||||
PROC_PRIO (tmp) = priosave; // Restore original priority
|
||||
return 0;
|
||||
}
|
||||
#endif /* SCHED_TYPE == SCHED_PRIO */
|
266
lib/bsp/xilkernel/src/src/sys/sched.c
Executable file
266
lib/bsp/xilkernel/src/src/sys/sched.c
Executable file
|
@ -0,0 +1,266 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file sched.c
|
||||
//! This file contains routines for process scheduling
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/entry.h>
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/decls.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
// Ready Queue - Array of N_PRIO process queues
|
||||
struct _queue ready_q[N_PRIO] ;
|
||||
signed char entry_mode = ENTRY_MODE_USER; // Current entry mode into kernel
|
||||
signed char resched = 0; // Indicates if rescheduling occurred elsewhere
|
||||
char did_resched = 0; // Indicates if the kernel completed the rescheduling
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
signed char sched_history[SCHED_HISTORY_SIZ];
|
||||
int shp = 0;
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
extern unsigned int budget_ticks;
|
||||
extern process_struct *ctx_save_process;
|
||||
extern int save_context (process_struct *);
|
||||
extern void restore_context (void);
|
||||
|
||||
int scheduler (void);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
void readyq_init(void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
|
||||
for (;i < N_PRIO; i++ ) {
|
||||
alloc_q (&ready_q[i], MAX_READYQ, READY_Q, sizeof(char), i);
|
||||
}
|
||||
}
|
||||
int scheduler (void)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_DEBUGMON
|
||||
debugmon_dump_sched_info ();
|
||||
#endif
|
||||
|
||||
if (current_process->state == PROC_DEAD) {
|
||||
ctx_save_process = NULL;
|
||||
prev_pid = -1;
|
||||
}
|
||||
else if (current_process->pcontext.isrflag == 1) { // If entered the kernel through an ISR, context saved in ISR itself
|
||||
ctx_save_process = NULL;
|
||||
prev_pid = current_pid;
|
||||
}
|
||||
else {
|
||||
ctx_save_process = current_process;
|
||||
prev_pid = current_pid;
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
sched_rr ();
|
||||
#elif SCHED_TYPE == SCHED_PRIO
|
||||
sched_prio ();
|
||||
#endif
|
||||
|
||||
if( current_pid == -1 ) {
|
||||
DBG_PRINT ("XMK: Unable to find schedulable process. Kernel Halt.\r\n") ;
|
||||
while(1);
|
||||
}
|
||||
|
||||
did_resched = 1; // scheduler indicates that it completed the rescheduling
|
||||
resched = 0; // scheduler always resets resched flag
|
||||
|
||||
#ifdef CONFIG_DEBUGMON
|
||||
debugmon_stack_check ();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
if (shp != SCHED_HISTORY_SIZ)
|
||||
sched_history[shp++] = current_pid;
|
||||
#endif
|
||||
|
||||
if (prev_pid == current_pid)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sched_rr
|
||||
//! @desc
|
||||
//! Round Robin Scheduler.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sched_rr (void)
|
||||
{
|
||||
signed char ready = -1;
|
||||
|
||||
// Enqueue only currently running processes. Else,
|
||||
// If PROC_DEAD, no need to enqueue
|
||||
// If PROC_WAIT or PROC_TIMED_WAIT, already enqueued in appropriate wait queue
|
||||
// If PROC_DELAY, is in one of the timer queues
|
||||
// If idle_task, then does not need to enter the queue
|
||||
if (current_process->state == PROC_RUN) {
|
||||
ptable[current_pid].state = PROC_READY;
|
||||
if(current_pid != idle_task_pid)
|
||||
penq (&ready_q[0], current_pid, 0);
|
||||
}
|
||||
|
||||
SET_CURRENT_PROCESS (-1);
|
||||
|
||||
while (ready_q[0].item_count != 0) {
|
||||
pdeq (&ready_q[0], &ready, 0);
|
||||
if (ptable[ready].state == PROC_DEAD) { // Flush out dead processes
|
||||
ready = -1;
|
||||
continue;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if (ready == -1)
|
||||
ready = idle_task_pid;
|
||||
|
||||
#if 0
|
||||
DBG_PRINT ("XMK: Scheduler: scheduled pid: ");
|
||||
putnum (ready);
|
||||
DBG_PRINT ("\r\n");
|
||||
#endif
|
||||
|
||||
ptable[ready].state = PROC_RUN;
|
||||
SET_CURRENT_PROCESS (ready);
|
||||
}
|
||||
#endif /* SCHED_TYPE == SCHED_RR */
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sched_prio
|
||||
//! @desc
|
||||
//! Pre-emptive strict priority scheduler
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void sched_prio (void)
|
||||
{
|
||||
int i;
|
||||
signed char ready = -1;
|
||||
|
||||
// Enqueue only currently running processes. Else,
|
||||
// If PROC_DEAD, no need to enqueue
|
||||
// If PROC_WAIT or PROC_TIMED_WAIT, already enqueued in appropriate wait queue
|
||||
// If PROC_DELAY, is in one of the timer queues
|
||||
// If idle_task, then does not need to enter the queue
|
||||
if (current_process->state == PROC_RUN) {
|
||||
ptable[current_pid].state = PROC_READY;
|
||||
if (current_pid != idle_task_pid)
|
||||
penq (&ready_q[ptable[current_pid].priority], current_pid, 0);
|
||||
}
|
||||
|
||||
SET_CURRENT_PROCESS (-1);
|
||||
|
||||
for (i=0; i <= PRIO_LOWEST; i++) {
|
||||
while (ready_q[i].item_count != 0) {
|
||||
pdeq (&ready_q[i], &ready, 0);
|
||||
if (ptable[ready].state == PROC_DEAD) { // Flush out dead processes
|
||||
ready = -1;
|
||||
continue;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
if (ready != -1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ready == -1)
|
||||
ready = idle_task_pid;
|
||||
|
||||
#if 0
|
||||
DBG_PRINT ("XMK: Scheduler: scheduled pid: ");
|
||||
putnum (ready);
|
||||
DBG_PRINT ("\r\n");
|
||||
#endif
|
||||
|
||||
ptable[ready].state = PROC_RUN;
|
||||
SET_CURRENT_PROCESS (ready);
|
||||
}
|
||||
#endif /* SCHED_TYPE == SCHED_PRIO */
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - suspend
|
||||
//! @desc
|
||||
//! Suspend a process inside the kernel. A rescheduling followed by the corresponding context
|
||||
//! switch occurs within this routine.
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - This routine is not expected to be invoked from within an ISR. i.e no suspension allowed in
|
||||
//! an ISR.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void suspend (void)
|
||||
{
|
||||
#ifdef CONFIG_STATS
|
||||
current_process->active_ticks++;
|
||||
budget_ticks++;
|
||||
#endif
|
||||
if (scheduler ()) {
|
||||
DBG_PRINT ("XMK: Scheduling error. Cannot suspend current process.\r\n");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
if (ctx_save_process != NULL)
|
||||
if (save_context (ctx_save_process)) // Save context returns 0 during save
|
||||
return; // When saved context is restored, returns a 1
|
||||
|
||||
restore_context ();
|
||||
}
|
258
lib/bsp/xilkernel/src/src/sys/syscall.S
Executable file
258
lib/bsp/xilkernel/src/src/sys/syscall.S
Executable file
|
@ -0,0 +1,258 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
//----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! syscall.S - Contains the system call table
|
||||
//-----------------------------------------------------------------------------------------//
|
||||
*/
|
||||
#include <os_config.h>
|
||||
|
||||
.global syscall_table
|
||||
|
||||
/*
|
||||
* System call table - System call number defined in syscall.h
|
||||
* If the module is not included in the system, then the location
|
||||
* in the table is replaced by 0.
|
||||
*/
|
||||
.section .rodata
|
||||
.align 2
|
||||
syscall_table: /* System call table */
|
||||
.long 0
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
.long sys_elf_process_create /* 1 */
|
||||
.long sys_elf_exit /* 2 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KILL
|
||||
.long sys_kill /* 3 */
|
||||
#else
|
||||
.long 0
|
||||
#endif
|
||||
.long sys_process_status /* 4 */
|
||||
.long sys_get_reentrancy /* 5 */
|
||||
#ifdef CONFIG_YIELD
|
||||
.long sys_yield /* 6 */
|
||||
#else
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
.long sys_get_currentPID /* 7 */
|
||||
.long 0 /* 8 */
|
||||
.long 0 /* 9 */
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
.long sys_pthread_create /* 10 */
|
||||
.long sys_pthread_exit /* 11 */
|
||||
.long sys_pthread_join /* 12 */
|
||||
.long sys_pthread_self /* 13 */
|
||||
.long sys_pthread_detach /* 14 */
|
||||
.long sys_pthread_equal /* 15 */
|
||||
#ifdef CONFIG_PRIOSCHED
|
||||
.long sys_pthread_getschedparam /* 16 */
|
||||
.long sys_pthread_setschedparam /* 17 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
.long sys_pthread_mutex_init /* 18 */
|
||||
.long sys_pthread_mutex_lock /* 19 */
|
||||
.long sys_pthread_mutex_trylock /* 20 */
|
||||
.long sys_pthread_mutex_unlock /* 21 */
|
||||
.long sys_pthread_mutex_destroy /* 22 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
.long 0 /* 23 */
|
||||
.long 0 /* 24 */
|
||||
.long 0 /* 25 */
|
||||
.long 0 /* 26 */
|
||||
.long 0 /* 27 */
|
||||
.long 0 /* 28 */
|
||||
.long 0 /* 29 */
|
||||
|
||||
#ifdef CONFIG_SEMA
|
||||
.long sys_sem_init /* 30 */
|
||||
.long sys_sem_wait_x /* 31 */
|
||||
.long sys_sem_trywait /* 32 */
|
||||
.long sys_sem_post /* 33 */
|
||||
.long sys_sem_destroy /* 34 */
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
.long sys_sem_open /* 35 */
|
||||
.long sys_sem_close /* 36 */
|
||||
.long sys_sem_unlink /* 37 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
.long sys_sem_getvalue /* 38 */
|
||||
#ifdef CONFIG_TIME
|
||||
.long sys_sem_timedwait /* 39 */
|
||||
#else
|
||||
.long 0
|
||||
#endif
|
||||
.long 0 /* 40 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
.long sys_msgget /* 41 */
|
||||
.long sys_msgctl /* 42 */
|
||||
.long sys_msgsnd /* 43 */
|
||||
.long sys_msgrcv /* 44 */
|
||||
.long 0 /* 45 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
.long sys_shmget /* 46 */
|
||||
.long sys_shmctl /* 47 */
|
||||
.long sys_shmat /* 48 */
|
||||
.long sys_shmdt /* 49 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
.long sys_bufcreate /* 50 */
|
||||
.long sys_bufdestroy /* 51 */
|
||||
.long sys_bufmalloc /* 52 */
|
||||
.long sys_buffree /* 53 */
|
||||
.long 0 /* 54 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
.long sys_xget_clock_ticks /* 55 */
|
||||
.long sys_sleep /* 56 */
|
||||
.long sys_time /* 57 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
.long sys_register_int_handler /* 58 */
|
||||
.long sys_unregister_int_handler /* 59 */
|
||||
.long sys_enable_interrupt /* 60 */
|
||||
.long sys_disable_interrupt /* 61 */
|
||||
.long sys_acknowledge_interrupt /* 62 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
.long sys_get_kernel_stats /* 63 */
|
||||
#else
|
||||
.long 0
|
||||
#endif
|
||||
.long 0 /* 64 */
|
||||
.long 0 /* 65 */
|
||||
.long 0 /* 66 */
|
||||
.long 0 /* 67 */
|
||||
.long 0 /* 68 */
|
||||
.long 0 /* 69 */
|
||||
.long 0 /* 70 */
|
||||
.long 0 /* 71 */
|
||||
.long 0 /* 72 */
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
.long xilsock_socket /* 73 */
|
||||
.long xilsock_bind /* 74 */
|
||||
.long xilsock_listen /* 75 */
|
||||
.long xilsock_accept /* 76 */
|
||||
.long xilsock_recv /* 77 */
|
||||
.long xilsock_send /* 78 */
|
||||
.long xilsock_recv /* 79 */
|
||||
.long xilsock_sendto /* 80 */
|
||||
.long xilsock_close /* 81 */
|
||||
#else
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
#endif
|
280
lib/bsp/xilkernel/src/src/sys/timer.c
Executable file
280
lib/bsp/xilkernel/src/src/sys/timer.c
Executable file
|
@ -0,0 +1,280 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************
|
||||
* File: timer.c
|
||||
* Description:
|
||||
* Timer functionality
|
||||
*****************************************************************************/
|
||||
#include <os_config.h>
|
||||
#include <sys/timer.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/xtrace.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
#define get_tmr_list_shadow(tmrlist) ((tmrlist == active_tmrs_a)?(active_tmrs_b):(active_tmrs_a))
|
||||
|
||||
static soft_tmr_t soft_tmrs[MAX_TMRS] ;
|
||||
static int* active_tmrs; // Pointer to the list of timer IDs that are currently active
|
||||
static int active_tmrs_a[MAX_TMRS]; // Actual timer ID lists A & B. (One is the shadow of the other)
|
||||
static int active_tmrs_b[MAX_TMRS];
|
||||
static int nactive;
|
||||
extern unsigned int kernel_ticks;
|
||||
extern struct _queue ready_q[];
|
||||
extern process_struct ptable[];
|
||||
extern process_struct *current_process;
|
||||
extern signed char resched;
|
||||
|
||||
static void handle_timeout (pid_t pid);
|
||||
static int get_free_tmr (void);
|
||||
static unsigned int
|
||||
ms_to_ticks (unsigned int ms);
|
||||
static unsigned int
|
||||
ticks_to_ms (unsigned int ticks);
|
||||
static void update_active_tmrs_list (pid_t pid);
|
||||
|
||||
void soft_tmr_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < MAX_TMRS; i++) {
|
||||
soft_tmrs[i].timeout = 0;
|
||||
soft_tmrs[i].pid = -1;
|
||||
active_tmrs_a[i] = -1;
|
||||
active_tmrs_b[i] = -1;
|
||||
}
|
||||
|
||||
active_tmrs = active_tmrs_a; // Set the current active timer list to "list A"
|
||||
nactive = 0;
|
||||
kernel_ticks = 0;
|
||||
}
|
||||
|
||||
static unsigned int ms_to_ticks (unsigned int ms)
|
||||
{
|
||||
return (ms / (SYSTMR_INTERVAL / SYSTMR_CLK_FREQ_KHZ));
|
||||
}
|
||||
|
||||
static unsigned int ticks_to_ms (unsigned int ticks)
|
||||
{
|
||||
return (ticks * (SYSTMR_INTERVAL / SYSTMR_CLK_FREQ_KHZ));
|
||||
}
|
||||
|
||||
static void handle_timeout (signed char pid)
|
||||
{
|
||||
|
||||
if (ptable[pid].blockq) {
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
pdelq (ptable[pid].blockq, pid);
|
||||
#elif SCHED_TYPE == SCHED_PRIO
|
||||
prio_pdelq (ptable[pid].blockq, pid);
|
||||
#endif
|
||||
ptable[pid].timeout = 1;
|
||||
ptable[pid].blockq = NULL;
|
||||
}
|
||||
|
||||
ptable[pid].state = PROC_READY;
|
||||
#if SCHED_TYPE == SCHED_RR
|
||||
penq (&ready_q[0], pid, 0);
|
||||
#else /* SCHED_TYPE == SCHED_PRIO */
|
||||
penq (&ready_q[ptable[pid].priority], pid, 0);
|
||||
#endif
|
||||
|
||||
resched = 1;
|
||||
}
|
||||
|
||||
|
||||
static void update_active_tmrs_list (pid_t pid)
|
||||
{
|
||||
int i;
|
||||
int* tmrshadow;
|
||||
int curactive = 0;
|
||||
|
||||
tmrshadow = get_tmr_list_shadow(active_tmrs); // Get the list that can act as a shadow to the current list
|
||||
for (i=0; i < nactive; i++) {
|
||||
if (soft_tmrs[active_tmrs[i]].pid == pid) { // This timer has been removed and is no longer active. Drop it
|
||||
soft_tmrs[active_tmrs[i]].pid = -1; // and also make it available for future allocations
|
||||
continue;
|
||||
}
|
||||
|
||||
tmrshadow[curactive] = active_tmrs[i]; // Append timer id to newly formed list
|
||||
curactive++;
|
||||
}
|
||||
|
||||
active_tmrs = tmrshadow;
|
||||
nactive = curactive;
|
||||
}
|
||||
|
||||
static int get_free_tmr (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (nactive == MAX_TMRS) // Break early if no timers left
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < MAX_TMRS; i++) {
|
||||
if (soft_tmrs[i].pid == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int add_tmr (pid_t pid, unsigned int ms)
|
||||
{
|
||||
int tmr;
|
||||
unsigned int ticks;
|
||||
|
||||
if ((tmr = get_free_tmr ()) < 0) {
|
||||
DPRINTF ("XMK: add_tmr -> Out of timers\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ticks = ms_to_ticks (ms);
|
||||
ticks = (ticks == 0) ? 1 : ticks; // Bump it up a little
|
||||
|
||||
soft_tmrs[tmr].pid = pid;
|
||||
soft_tmrs[tmr].timeout = ticks;
|
||||
active_tmrs[nactive] = tmr;
|
||||
nactive++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int remove_tmr (pid_t pid)
|
||||
{
|
||||
int i;
|
||||
unsigned int remain = 0;
|
||||
|
||||
for (i = 0; i < MAX_TMRS; i++) {
|
||||
if (soft_tmrs[i].pid == pid) {
|
||||
remain = ticks_to_ms (soft_tmrs[i].timeout);
|
||||
update_active_tmrs_list (pid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return remain;
|
||||
}
|
||||
|
||||
// Timer lists A&B.
|
||||
// One acts as a shadow to the other always. On every timer update event,
|
||||
// the current list is operated on, while the shadow list keeps getting updates
|
||||
void soft_tmr_handler (void)
|
||||
{
|
||||
int i;
|
||||
int* tmrshadow;
|
||||
int curactive = 0;
|
||||
|
||||
tmrshadow = get_tmr_list_shadow(active_tmrs); // Get the list that can act as a shadow to the current list
|
||||
for (i=0; i < nactive; i++) {
|
||||
soft_tmrs[active_tmrs[i]].timeout--;
|
||||
if (soft_tmrs[active_tmrs[i]].timeout == 0) { // Timer expired. Unblock the process
|
||||
handle_timeout (soft_tmrs[active_tmrs[i]].pid);
|
||||
soft_tmrs[active_tmrs[i]].pid = -1;
|
||||
}
|
||||
else {
|
||||
tmrshadow[curactive] = active_tmrs[i]; // Append timer id to newly formed list
|
||||
curactive++;
|
||||
}
|
||||
}
|
||||
|
||||
active_tmrs = tmrshadow;
|
||||
nactive = curactive;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_xget_clock_ticks
|
||||
//! @desc
|
||||
//! Return kernel ticks elapsed since system start (does not convey overflow information)
|
||||
//! @param
|
||||
//! - None
|
||||
//! @return
|
||||
//! - Number of kernel ticks elapsed
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
unsigned int sys_xget_clock_ticks (void)
|
||||
{
|
||||
return kernel_ticks;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_time
|
||||
//! @desc
|
||||
//! Return number of seconds elapsed since kernel start.
|
||||
//! @param
|
||||
//! - timer is a pointer to the time_t structure to return the result in
|
||||
//! @return
|
||||
//! - Number of seconds elapsed since kernel start
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
time_t sys_time (time_t *timer)
|
||||
{
|
||||
time_t secs = 0;
|
||||
|
||||
secs = ((kernel_ticks * (SYSTMR_INTERVAL / SYSTMR_CLK_FREQ_KHZ)) / 1000);
|
||||
|
||||
if (timer)
|
||||
*timer = secs;
|
||||
|
||||
return secs;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - sys_sleep
|
||||
//! @desc
|
||||
//! Suspend current process for specified number of ticks
|
||||
//! 1 tick = one timer interrupt received by the kernel
|
||||
//! @param
|
||||
//! - ms is the number of milliseconds to sleep this task.
|
||||
//! @return
|
||||
//! - Number of milliseconds unslept for. 0 - complete success
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
unsigned sys_sleep (unsigned int ms)
|
||||
{
|
||||
pid_t cpid = sys_get_currentPID();
|
||||
|
||||
if (add_tmr (cpid, ms) == -1)
|
||||
return ms;
|
||||
|
||||
current_process->state = PROC_DELAY;
|
||||
suspend ();
|
||||
|
||||
// Awaken here after timeout
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TIME */
|
272
lib/bsp/xilkernel/src/src/sys/xilkernel_main.c
Executable file
272
lib/bsp/xilkernel/src/src/sys/xilkernel_main.c
Executable file
|
@ -0,0 +1,272 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file xilkernel_main.c
|
||||
//! Initialises the system by calling sys_init(), hw_init() and blocks the kernel
|
||||
//! On first timer interrupt the first process gets scheduled.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <xmk.h>
|
||||
#include <os_config.h>
|
||||
|
||||
#include <xil_exception.h>
|
||||
|
||||
#ifdef MB_XILKERNEL
|
||||
#include <sys/process.h>
|
||||
#endif
|
||||
|
||||
#ifdef PPC_XILKERNEL
|
||||
#include <config/config_param.h>
|
||||
#include <config/config_cparam.h>
|
||||
#include <sys/ktypes.h>
|
||||
#include <xparameters.h>
|
||||
#include <sys/process.h>
|
||||
#include <xpseudo_asm.h>
|
||||
#include <xtime_l.h>
|
||||
#include <sys/syscall.h>
|
||||
#endif /* PPC_XILKERNEL */
|
||||
#include <sys/decls.h>
|
||||
#include <sys/init.h>
|
||||
#include <sys/mem.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#ifdef CONFIG_STATIC_ELF_PROCESS_SUPPORT
|
||||
extern struct _process_init se_process_table[] ;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
extern pthread_attr_t default_attr;
|
||||
|
||||
#ifdef CONFIG_STATIC_PTHREAD_SUPPORT
|
||||
extern struct _elf_pthread_init kb_pthread_table[];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void idle_task (void);
|
||||
extern void init_idle_task (void);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xilkernel_main
|
||||
//! @desc
|
||||
//! Entry point of the kernel
|
||||
//! @return
|
||||
//! - Nothing.
|
||||
//! @note
|
||||
//! - Routine does not return. (Caller does not get back control)
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void xilkernel_main(void)
|
||||
{
|
||||
DBG_PRINT("XMK: Starting kernel.\r\n");
|
||||
|
||||
xilkernel_init ();
|
||||
xilkernel_start ();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xilkernel_init
|
||||
//! @desc
|
||||
//! Initialize the system - This function is called at the start of system.
|
||||
//! It initializes the system.
|
||||
//! - Initializes the process vector table.
|
||||
//! - Creates the Idle process (pid - 0).
|
||||
//! - Creates the static set of processes.
|
||||
//! @return
|
||||
//! - Nothing.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void xilkernel_init(void)
|
||||
{
|
||||
unsigned int i = 0 ;
|
||||
|
||||
DBG_PRINT("XMK: Initializing Hardware.\r\n");
|
||||
hw_init(); // Do hardware specific initialization
|
||||
|
||||
DBG_PRINT("XMK: System initialization.\r\n");
|
||||
for( ; i < MAX_PROCESS_CONTEXTS; i++ ) {
|
||||
ptable[i].is_allocated = 0 ;
|
||||
ptable[i].pcontext.isrflag = 0;
|
||||
}
|
||||
|
||||
#ifdef MB_XILKERNEL
|
||||
kernel_sp = (void*)((unsigned int)&_stack + SSTACK_PTR_ADJUST);
|
||||
#elif defined(PPC_XILKERNEL)
|
||||
kernel_sp = (void*)((unsigned int)&__stack + SSTACK_PTR_ADJUST);
|
||||
#endif
|
||||
readyq_init();
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
pthread_init();
|
||||
#endif
|
||||
#ifdef CONFIG_SEMA
|
||||
sem_heap_init();
|
||||
#endif
|
||||
#ifdef CONFIG_MSGQ
|
||||
msgq_init();
|
||||
#endif
|
||||
#ifdef CONFIG_SHM
|
||||
shm_init();
|
||||
#endif
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
bufmalloc_init ();
|
||||
#endif
|
||||
|
||||
init_idle_task ();
|
||||
|
||||
#ifdef CONFIG_STATIC_ELF_PROCESS_SUPPORT
|
||||
se_process_init() ; // Create statically specified separate executable processes
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STATIC_PTHREAD_SUPPORT
|
||||
kb_pthread_init (); // Create statically specified kernel bundled threads
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
soft_tmr_init ();
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xilkernel_start
|
||||
//! @desc
|
||||
//! Start the kernel by enabling interrupts and starting to execute the idle task.
|
||||
//! @return
|
||||
//! - Nothing.
|
||||
//! @note
|
||||
//! - Routine does not return.
|
||||
//! @desc
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void xilkernel_start (void)
|
||||
{
|
||||
DBG_PRINT("XMK: Process scheduling starts.\r\n");
|
||||
Xil_ExceptionEnable();
|
||||
idle_task (); // Does not return
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STATIC_ELF_PROCESS_SUPPORT
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - se_process_init
|
||||
//! @desc
|
||||
//! Create the statically specified set of separate executable processes.
|
||||
//! @return
|
||||
//! - 0 on success
|
||||
//! - -1 on error
|
||||
//! @note
|
||||
//! - Used only in the case of separate executable process support
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int se_process_init(void)
|
||||
{
|
||||
struct _process_init *pinit ;
|
||||
unsigned int i = 0 ;
|
||||
|
||||
// Atleast a single process should be loaded during initialisation.
|
||||
pinit = se_process_table;
|
||||
for( i = 0; i < N_INIT_PROCESS; i++) {
|
||||
if (sys_elf_process_create((void*)pinit->p_start_addr, pinit->priority) < 0) {
|
||||
DBG_PRINT ("XMK: se_process_init: sys_process_create failed.\r\n");
|
||||
return -1;
|
||||
}
|
||||
pinit++ ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_STATIC_ELF_PROCESS_SUPPORT */
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
#ifdef CONFIG_STATIC_PTHREAD_SUPPORT
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - kb_pthread_init
|
||||
//! @desc
|
||||
//! Create the statically specified pthreads that do not have an ELF file associated with it.
|
||||
//! Threads in kernel space. Stack allocated from BSS memory pool.
|
||||
//! @return
|
||||
//! - 0 on success
|
||||
//! - error code from sys_pthread_create
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
int kb_pthread_init(void)
|
||||
{
|
||||
struct _elf_pthread_init *pinit ;
|
||||
unsigned int i = 0 ;
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr = default_attr;
|
||||
int ret;
|
||||
|
||||
// Load the system processes to run during init.
|
||||
pinit = kb_pthread_table;
|
||||
|
||||
for( i=0; i<N_INIT_SELF_PTHREADS; i++) {
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
attr.schedparam.sched_priority = pinit->priority;
|
||||
#endif
|
||||
ret = sys_pthread_create (&tid, &attr, (void*)pinit->start_func, NULL);
|
||||
if (ret != 0) {
|
||||
DBG_PRINT("XMK: kb_pthread_init: sys_pthread_create failed.\r\n");
|
||||
return -1;
|
||||
}
|
||||
pinit++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_STATIC_PTHREAD_SUPPORT */
|
||||
|
||||
|
||||
int xmk_add_static_thread(void* (*start_routine)(void *), int sched_priority)
|
||||
{
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr = default_attr;
|
||||
int ret;
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
attr.schedparam.sched_priority = sched_priority;
|
||||
#endif
|
||||
sched_priority = 0; /* Dummy to remove compilation issues */
|
||||
|
||||
ret = sys_pthread_create (&tid, &attr, start_routine, NULL);
|
||||
if (ret != 0) {
|
||||
DBG_PRINT("XMK: xmk_add_static_thread: sys_pthread_create failed.\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
187
lib/bsp/xilkernel/src/src/sys/xtrace.c
Executable file
187
lib/bsp/xilkernel/src/src/sys/xtrace.c
Executable file
|
@ -0,0 +1,187 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file xtrace.c
|
||||
//!
|
||||
//! XMK API for tracing kernel level and custom user events.
|
||||
//! Requires trace memory in the system accessible to program.
|
||||
//! @note - This feature is for internal use only.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/decls.h>
|
||||
#include <sys/xtrace.h>
|
||||
|
||||
#ifdef CONFIG_XTRACE
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Declarations
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
const char *xtrace_event_name[] = {
|
||||
"SCHED",
|
||||
"SEM",
|
||||
"TIMER",
|
||||
"CUSTOM"
|
||||
};
|
||||
|
||||
const char *xtrace_action_name[] = {
|
||||
"resched",
|
||||
"wait",
|
||||
"timewait",
|
||||
"wait_timeout",
|
||||
"wait_unblock",
|
||||
"acquire",
|
||||
"post",
|
||||
"post_unblock",
|
||||
"timeout",
|
||||
"tick",
|
||||
"add",
|
||||
"remove",
|
||||
"action1",
|
||||
"action2",
|
||||
"action3",
|
||||
"action4",
|
||||
"action5",
|
||||
"action6"
|
||||
};
|
||||
|
||||
extern pid_t current_pid;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Data
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
unsigned int xtrace_first, xtrace_last, xtrace_count;
|
||||
xtrace_pkt_t *xtracebuf = (xtrace_pkt_t *)(CONFIG_XTRACE_MEM_START + 8);
|
||||
unsigned int xtrace_off;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// Definitions
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xtrace_log_event
|
||||
//!
|
||||
//!
|
||||
//! @param
|
||||
//! -
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void xtrace_log_event (enum xtrace_event event, enum xtrace_action action,
|
||||
unsigned int resource, unsigned int custom0, unsigned int custom1)
|
||||
{
|
||||
if (xtrace_off)
|
||||
return;
|
||||
|
||||
xtracebuf[xtrace_last].event = event;
|
||||
xtracebuf[xtrace_last].pid = current_pid;
|
||||
xtracebuf[xtrace_last].resource = resource;
|
||||
xtracebuf[xtrace_last].action = action;
|
||||
xtracebuf[xtrace_last].custom[0] = custom0;
|
||||
xtracebuf[xtrace_last].custom[1] = custom1;
|
||||
|
||||
if (xtrace_count != CONFIG_XTRACE_MAX_COUNT)
|
||||
xtrace_count++;
|
||||
|
||||
xtrace_last++;
|
||||
if (xtrace_last == CONFIG_XTRACE_MAX_COUNT)
|
||||
xtrace_last = 0;
|
||||
|
||||
if (xtrace_last == xtrace_first) {
|
||||
xtrace_first++;
|
||||
if (xtrace_first == CONFIG_XTRACE_MAX_COUNT)
|
||||
xtrace_first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
// @func - xtrace_print_log
|
||||
//!
|
||||
//!
|
||||
//! @param
|
||||
//! -
|
||||
//! @return
|
||||
//! - Nothing
|
||||
//! @note
|
||||
//! - None
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
void xtrace_print_log (int count, int last)
|
||||
{
|
||||
int i, start, end;
|
||||
|
||||
DPRINTF ("XTrace Log\r\n");
|
||||
DPRINTF ("\tTotal events recorded: %d.\r\n", xtrace_count);
|
||||
|
||||
if (count == 0)
|
||||
count = xtrace_count;
|
||||
|
||||
if (last) {
|
||||
start = (xtrace_last - count - 1);
|
||||
if (start < 0)
|
||||
start = (CONFIG_XTRACE_MAX_COUNT + start);
|
||||
} else
|
||||
start = xtrace_first;
|
||||
|
||||
end = (start + count) % CONFIG_XTRACE_MAX_COUNT;
|
||||
|
||||
DPRINTF ("\tDumping (%d) %s events next --\r\n", count, (last ? "trailing" : "beginning"));
|
||||
|
||||
i = start;
|
||||
while (i != end) {
|
||||
if (xtracebuf[i].event >= XCUSTOM_EVENT) {
|
||||
DPRINTF ("E%04d: [%6s]-(%15s) PID(%03d) on (%03d). custom - [0x%x], [0x%x]\r\n",
|
||||
i,
|
||||
xtrace_event_name[xtracebuf[i].event],
|
||||
xtrace_action_name[xtracebuf[i].action],
|
||||
xtracebuf[i].pid,
|
||||
xtracebuf[i].resource,
|
||||
xtracebuf[i].custom[0],
|
||||
xtracebuf[i].custom[1]);
|
||||
} else {
|
||||
DPRINTF ("E%04d: [%6s]-(%15s) PID(%03d) on (%03d).\r\n",
|
||||
i,
|
||||
xtrace_event_name[xtracebuf[i].event],
|
||||
xtrace_action_name[xtracebuf[i].action],
|
||||
xtracebuf[i].pid,
|
||||
xtracebuf[i].resource);
|
||||
}
|
||||
|
||||
if (++i == CONFIG_XTRACE_MAX_COUNT)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_XTRACE */
|
63
lib/bsp/xilkernel/src/syscall/Makefile
Executable file
63
lib/bsp/xilkernel/src/syscall/Makefile
Executable file
|
@ -0,0 +1,63 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for libw.a
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:52 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
OBJS = libintr.o libmem.o libmsgq.o libprocess.o libpthread.o libsemaphore.o libshm.o libtimer.o
|
||||
INCLUDEDIR = ../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
libs: arch-libs $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -D__ASM__ -c $< -o $@ $(INCLUDES)
|
||||
|
||||
arch-libs:
|
||||
$(MAKE) -C arch/$(ARCH) CFLAGS="$(CFLAGS)" CC="$(CC)" AR="$(AR)"
|
||||
|
||||
clean:
|
||||
$(MAKE) -C arch/$(ARCH) clean
|
||||
rm -f $(OBJS)
|
59
lib/bsp/xilkernel/src/syscall/arch/microblaze/Makefile
Executable file
59
lib/bsp/xilkernel/src/syscall/arch/microblaze/Makefile
Executable file
|
@ -0,0 +1,59 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for libw.a
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:52 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
OBJS = mksyscall.o
|
||||
INCLUDEDIR = ../../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
all : $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -D__ASM__ -c $< -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
58
lib/bsp/xilkernel/src/syscall/arch/microblaze/mksyscall.S
Executable file
58
lib/bsp/xilkernel/src/syscall/arch/microblaze/mksyscall.S
Executable file
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! mksyscall.S - System call stub
|
||||
-----------------------------------------------------------------------------------------//*/
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/arch.h>
|
||||
|
||||
|
||||
/* make_syscall (param1, param2, param3, param4, param5, syscall_num);
|
||||
* r5, r6, r7, r8, r9, r10
|
||||
*
|
||||
*/
|
||||
|
||||
.global make_syscall
|
||||
.section .text
|
||||
.align 2
|
||||
.ent make_syscall
|
||||
make_syscall:
|
||||
addi r1, r1, -4;
|
||||
sw r15, r0, r1; /* Save link register */
|
||||
bralid r15, (CONFIG_BASE_VECTORS + 8); /* Make system call. Parameters in registers. System call number in r10 */
|
||||
nop;
|
||||
lw r15, r0, r1; /* Restore link register */
|
||||
rtsd r15, 8;
|
||||
addik r1, r1, 4;
|
||||
.end make_syscall
|
62
lib/bsp/xilkernel/src/syscall/arch/ppc/Makefile
Executable file
62
lib/bsp/xilkernel/src/syscall/arch/ppc/Makefile
Executable file
|
@ -0,0 +1,62 @@
|
|||
##############################################################################
|
||||
#
|
||||
# (c) Copyright 2010 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||
# and is protected under U.S. and international copyright and other
|
||||
# intellectual property laws.
|
||||
#
|
||||
# DISCLAIMER
|
||||
# This disclaimer is not a license and does not grant any rights to the
|
||||
# materials distributed herewith. Except as otherwise provided in a valid
|
||||
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||
# negligence, or under any other theory of liability) for any loss or damage
|
||||
# of any kind or nature related to, arising under or in connection with these
|
||||
# materials, including for any direct, or any indirect, special, incidental,
|
||||
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||
# or any type of loss or damage suffered as a result of any action brought by
|
||||
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||
# Xilinx had been advised of the possibility of the same.
|
||||
#
|
||||
# CRITICAL APPLICATIONS
|
||||
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||
# any application requiring fail-safe performance, such as life-support or
|
||||
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||
# applications related to the deployment of airbags, or any other applications
|
||||
# that could lead to death, personal injury, or severe property or
|
||||
# environmental damage (individually and collectively, "Critical
|
||||
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||
# and regulations governing limitations on product liability.
|
||||
#
|
||||
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||
# AT ALL TIMES.
|
||||
#
|
||||
# Makefile for libw.a
|
||||
#
|
||||
# $Id: Makefile,v 1.1.2.1 2011/08/25 12:12:52 anirudh Exp $
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
include ../../../cpu.make
|
||||
|
||||
OBJS = mksyscall${CPU_TYPE}.o
|
||||
INCLUDEDIR = ../../../../../../
|
||||
INCLUDES = -I$(INCLUDEDIR)/include
|
||||
|
||||
|
||||
all : $(OBJS)
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@ $(INCLUDES)
|
||||
|
||||
%.o:%.S
|
||||
$(CC) $(CFLAGS) -c -D__ASM__ $< -o $@ $(INCLUDES)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS)
|
62
lib/bsp/xilkernel/src/syscall/arch/ppc/mksyscall405.S
Executable file
62
lib/bsp/xilkernel/src/syscall/arch/ppc/mksyscall405.S
Executable file
|
@ -0,0 +1,62 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! mksyscall.S - System call stub
|
||||
-----------------------------------------------------------------------------------------//*/
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/arch.h>
|
||||
|
||||
|
||||
/* make_syscall (param1, param2, param3, param4, param5, syscall_num);
|
||||
* r3, r4, r5, r6, r7, r8
|
||||
*
|
||||
* System call handler located at system call exception
|
||||
*/
|
||||
|
||||
.global make_syscall
|
||||
.section .text
|
||||
.align 2
|
||||
.type make_syscall@function
|
||||
make_syscall:
|
||||
stwu 1, -8(1); /* Make space on the stack and save backchain */
|
||||
mflr 0;
|
||||
stw 0, 12(1); /* Save link register */
|
||||
mfevpr 11; /* Get the exception vector base */
|
||||
addi 0, 11, 0x0C00;
|
||||
mtlr 0;
|
||||
blrl;
|
||||
lwz 0, 12(1);
|
||||
mtlr 0;
|
||||
addi 1, 1, 8;
|
||||
blr;
|
63
lib/bsp/xilkernel/src/syscall/arch/ppc/mksyscall440.S
Executable file
63
lib/bsp/xilkernel/src/syscall/arch/ppc/mksyscall440.S
Executable file
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*----------------------------------------------------------------------------------------//
|
||||
//! @file
|
||||
//! mksyscall.S - System call stub
|
||||
-----------------------------------------------------------------------------------------//*/
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/arch.h>
|
||||
|
||||
|
||||
/* make_syscall (param1, param2, param3, param4, param5, syscall_num);
|
||||
* r3, r4, r5, r6, r7, r8
|
||||
*
|
||||
* System call handler located at system call exception
|
||||
*/
|
||||
|
||||
.global make_syscall
|
||||
.section .text
|
||||
.align 2
|
||||
.type make_syscall@function
|
||||
make_syscall:
|
||||
stwu 1, -8(1); /* Make space on the stack and save backchain */
|
||||
mflr 0;
|
||||
stw 0, 12(1); /* Save link register */
|
||||
mfivpr 11; /* Get the exception vector base */
|
||||
mfivor8 12;
|
||||
add 0, 11, 12;
|
||||
mtlr 0;
|
||||
blrl;
|
||||
lwz 0, 12(1);
|
||||
mtlr 0;
|
||||
addi 1, 1, 8;
|
||||
blr;
|
68
lib/bsp/xilkernel/src/syscall/libintr.c
Executable file
68
lib/bsp/xilkernel/src/syscall/libintr.c
Executable file
|
@ -0,0 +1,68 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libintr.c
|
||||
//! API to manipulate interrupt controller and register user handlers for
|
||||
//! interrupts in the system
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/intr.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_INTC
|
||||
unsigned int register_int_handler (int_id_t intr_id, void (*handler)(void*), void *callback)
|
||||
{
|
||||
return (unsigned int) make_syscall ((void*) (unsigned int)intr_id, (void*)handler, (void*)callback, NULL, NULL, SC_REGISTER_INT_HANDLER);
|
||||
}
|
||||
|
||||
void unregister_int_handler (int_id_t intr_id)
|
||||
{
|
||||
make_syscall ((void*) (unsigned int) intr_id, NULL, NULL, NULL, NULL, SC_UNREGISTER_INT_HANDLER);
|
||||
}
|
||||
|
||||
void enable_interrupt (int_id_t intr_id)
|
||||
{
|
||||
make_syscall ((void*) (unsigned int) intr_id, NULL, NULL, NULL, NULL, SC_ENABLE_INTERRUPT);
|
||||
}
|
||||
|
||||
void disable_interrupt (int_id_t intr_id)
|
||||
{
|
||||
make_syscall ((void*) (unsigned int)intr_id, NULL, NULL, NULL, NULL, SC_DISABLE_INTERRUPT);
|
||||
}
|
||||
|
||||
void acknowledge_interrupt (int_id_t intr_id)
|
||||
{
|
||||
make_syscall ((void*) (unsigned int)intr_id, NULL, NULL, NULL, NULL, SC_ACKNOWLEDGE_INTERRUPT);
|
||||
}
|
||||
#endif /* CONFIG_INTC */
|
62
lib/bsp/xilkernel/src/syscall/libmem.c
Executable file
62
lib/bsp/xilkernel/src/syscall/libmem.c
Executable file
|
@ -0,0 +1,62 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libmem.c
|
||||
//! This contains system call wrapper functions for Dynamic buffer management.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/bufmalloc.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_BUFMALLOC
|
||||
int bufcreate (membuf_t *mbuf, void *memptr, int nblks, size_t blksiz)
|
||||
{
|
||||
return (int)make_syscall ((void*)mbuf, memptr, (void*)nblks, (void*)blksiz, NULL, SC_BUFCREATE);
|
||||
}
|
||||
|
||||
int bufdestroy (membuf_t mbuf)
|
||||
{
|
||||
return (int)make_syscall ((void*)mbuf, NULL, NULL, NULL, NULL, SC_BUFDESTROY);
|
||||
}
|
||||
|
||||
void* bufmalloc (membuf_t mbuf, size_t siz)
|
||||
{
|
||||
return (void*)make_syscall ((void*)mbuf, (void*)siz, NULL, NULL, NULL, SC_BUFMALLOC);
|
||||
}
|
||||
|
||||
void buffree (membuf_t mbuf, void *mem)
|
||||
{
|
||||
make_syscall ((void*)mbuf, (void*)mem, NULL, NULL, NULL, SC_BUFFREE);
|
||||
}
|
||||
#endif /* CONFIG_MALLOC */
|
63
lib/bsp/xilkernel/src/syscall/libmsgq.c
Executable file
63
lib/bsp/xilkernel/src/syscall/libmsgq.c
Executable file
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libmsgq.c
|
||||
//! This contains system call wrapper functions for Message Queue.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/kmsg.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_MSGQ
|
||||
int msgget(key_t key, int msgflg)
|
||||
{
|
||||
return (int) make_syscall ((void*)key, (void*)msgflg, NULL, NULL, NULL, SC_MSGGET);
|
||||
}
|
||||
|
||||
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
return (int) make_syscall ((void*)msqid, (void*)cmd, (void*)buf, NULL, NULL, SC_MSGCTL);
|
||||
}
|
||||
|
||||
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
|
||||
{
|
||||
return (int) make_syscall ((void*)msqid, (void*)msgp, (void*)msgsz, (void*)msgflg, NULL, SC_MSGSND);
|
||||
}
|
||||
|
||||
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
||||
{
|
||||
return (ssize_t) make_syscall ((void*)msqid, (void*)msgp, (void*)msgsz, (void*)msgtyp, (void*)msgflg, SC_MSGRCV);
|
||||
}
|
||||
#endif /* CONFIG_MSGQ */
|
101
lib/bsp/xilkernel/src/syscall/libprocess.c
Executable file
101
lib/bsp/xilkernel/src/syscall/libprocess.c
Executable file
|
@ -0,0 +1,101 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libprocess.c
|
||||
//! This contains system call wrapper functions for Process Management.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/stats.h>
|
||||
#include <sys/ktypes.h>
|
||||
|
||||
reent_t *lreent = NULL;
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
reent_t* get_reentrancy (void)
|
||||
{
|
||||
return (reent_t*) make_syscall (NULL, NULL, NULL, NULL, NULL, SC_GET_REENTRANCY);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ELF_PROCESS
|
||||
pid_t elf_process_create (void* start, int prio)
|
||||
{
|
||||
return (int) make_syscall (start, (void*)prio, NULL, NULL, NULL, SC_PROCESS_CREATE);
|
||||
}
|
||||
|
||||
int elf_process_exit (void)
|
||||
{
|
||||
return (int) make_syscall ( NULL, NULL, NULL, NULL, NULL, SC_PROCESS_EXIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KILL
|
||||
int kill (pid_t pid)
|
||||
{
|
||||
return (int) make_syscall ((void*)(int)pid, NULL, NULL, NULL, NULL, SC_PROCESS_KILL);
|
||||
}
|
||||
#endif
|
||||
|
||||
int process_status (pid_t pid, p_stat *ps)
|
||||
{
|
||||
return (int) make_syscall ((void*)(int)pid, (void*)ps, NULL, NULL, NULL, SC_PROCESS_STATUS);
|
||||
}
|
||||
|
||||
pid_t get_currentPID (void)
|
||||
{
|
||||
return (int) make_syscall (NULL, NULL, NULL, NULL, NULL, SC_PROCESS_GETPID);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_YIELD
|
||||
int yield (void)
|
||||
{
|
||||
return (int) make_syscall (NULL, NULL, NULL, NULL, NULL, SC_PROCESS_YIELD);
|
||||
}
|
||||
#endif /* CONFIG_YIELD */
|
||||
|
||||
#ifdef CONFIG_STATS
|
||||
int get_kernel_stats (kstats_t *stats)
|
||||
{
|
||||
return (int) make_syscall ((void*)stats, NULL, NULL, NULL, NULL, SC_GET_KERNEL_STATS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int* __errno (void)
|
||||
{
|
||||
if (lreent == NULL)
|
||||
lreent = get_reentrancy ();
|
||||
|
||||
return &(lreent->_errno);
|
||||
}
|
259
lib/bsp/xilkernel/src/syscall/libpthread.c
Executable file
259
lib/bsp/xilkernel/src/syscall/libpthread.c
Executable file
|
@ -0,0 +1,259 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libpthread.c
|
||||
//! This contains system call wrapper functions for pthread functionality.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <stdio.h>
|
||||
#include <os_config.h>
|
||||
#include <sys/process.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <config/config_param.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/ksched.h>
|
||||
#include <sys/kpthread.h>
|
||||
#include <sys/ktypes.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_PTHREAD_SUPPORT
|
||||
int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_func)(void *), void *param)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread, (void*)attr, (void*)start_func, (void*)param, NULL, SC_PTHREAD_CREATE);
|
||||
}
|
||||
|
||||
void pthread_exit (void *retval)
|
||||
{
|
||||
make_syscall ((void*)retval, NULL, NULL, NULL, NULL, SC_PTHREAD_EXIT);
|
||||
}
|
||||
|
||||
int pthread_join (pthread_t thread, void **retval)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread, (void*)retval, NULL, NULL, NULL, SC_PTHREAD_JOIN);
|
||||
}
|
||||
|
||||
pthread_t pthread_self (void)
|
||||
{
|
||||
return (pthread_t) make_syscall (NULL, NULL, NULL, NULL, NULL, SC_PTHREAD_SELF);
|
||||
}
|
||||
|
||||
int pthread_detach (pthread_t thread)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread, NULL, NULL, NULL, NULL, SC_PTHREAD_DETACH);
|
||||
}
|
||||
|
||||
int pthread_equal (pthread_t thread_1, pthread_t thread_2)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread_1, (void*)thread_2, NULL, NULL, NULL, SC_PTHREAD_EQUAL);
|
||||
}
|
||||
|
||||
int pthread_attr_init (pthread_attr_t *attr)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
attr->contentionscope = PTHREAD_SCOPE_SYSTEM;
|
||||
attr->schedparam.sched_priority = PRIO_LOWEST;
|
||||
attr->detachstate = PTHREAD_CREATE_DETACHED;
|
||||
attr->stackaddr = NULL;
|
||||
attr->stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_destroy (pthread_attr_t *attr)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
attr->contentionscope = PTHREAD_INVALID;
|
||||
attr->schedparam.sched_priority = PTHREAD_INVALID;
|
||||
attr->detachstate = PTHREAD_INVALID;
|
||||
attr->stackaddr = NULL;
|
||||
attr->stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
int pthread_attr_setschedparam (pthread_attr_t *attr, const struct sched_param *spar)
|
||||
{
|
||||
if (attr == NULL || spar == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (spar->sched_priority < PRIO_HIGHEST || spar->sched_priority > PRIO_LOWEST)
|
||||
return ENOTSUP;
|
||||
|
||||
attr->schedparam.sched_priority = spar->sched_priority;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *spar)
|
||||
{
|
||||
if (attr == NULL || spar == NULL)
|
||||
return EINVAL;
|
||||
|
||||
spar->sched_priority = attr->schedparam.sched_priority;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int pthread_attr_getdetachstate (const pthread_attr_t *attr, int *dstate)
|
||||
{
|
||||
if (attr == NULL || ((attr->detachstate != PTHREAD_CREATE_DETACHED) && (attr->detachstate != PTHREAD_CREATE_JOINABLE)))
|
||||
return EINVAL;
|
||||
|
||||
*dstate = attr->detachstate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setdetachstate (pthread_attr_t *attr, int dstate)
|
||||
{
|
||||
if (attr == NULL || ((dstate != PTHREAD_CREATE_DETACHED) && (dstate != PTHREAD_CREATE_JOINABLE)))
|
||||
return EINVAL;
|
||||
|
||||
attr->detachstate = dstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, size_t *stacksize)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
*stackaddr = attr->stackaddr;
|
||||
*stacksize = attr->stacksize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize)
|
||||
{
|
||||
#ifdef MB_XILKERNEL
|
||||
#define SALIGN 0x3
|
||||
#else
|
||||
#define SALIGN 0x7
|
||||
#endif
|
||||
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if ((unsigned int)stackaddr & SALIGN)
|
||||
return EINVAL;
|
||||
|
||||
attr->stackaddr = stackaddr;
|
||||
attr->stacksize = stacksize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SCHED_TYPE == SCHED_PRIO
|
||||
int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread, (void*)policy, (void*)param, NULL, NULL, SC_PTHREAD_GETSCHEDPARAM);
|
||||
}
|
||||
|
||||
int pthread_setschedparam (pthread_t thread, int policy, struct sched_param *param)
|
||||
{
|
||||
return (int) make_syscall ((void*)thread, (void*)policy, (void*)param, NULL, NULL, SC_PTHREAD_SETSCHEDPARAM);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PTHREAD_MUTEX
|
||||
int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
||||
{
|
||||
return (int) make_syscall ((void*)mutex, (void*)attr, NULL, NULL, NULL, SC_PTHREAD_MUTEX_INIT);
|
||||
}
|
||||
|
||||
int pthread_mutex_destroy (pthread_mutex_t *mutex)
|
||||
{
|
||||
return (int) make_syscall ((void*)mutex, NULL, NULL, NULL, NULL, SC_PTHREAD_MUTEX_DESTROY);
|
||||
}
|
||||
|
||||
int pthread_mutex_lock (pthread_mutex_t *mutex)
|
||||
{
|
||||
return (int) make_syscall ((void*)mutex, NULL, NULL, NULL, NULL, SC_PTHREAD_MUTEX_LOCK);
|
||||
}
|
||||
|
||||
int pthread_mutex_trylock (pthread_mutex_t *mutex)
|
||||
{
|
||||
return (int) make_syscall ((void*)mutex, NULL, NULL, NULL, NULL, SC_PTHREAD_MUTEX_TRYLOCK);
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock (pthread_mutex_t *mutex)
|
||||
{
|
||||
return (int) make_syscall ((void*)mutex, NULL, NULL, NULL, NULL, SC_PTHREAD_MUTEX_UNLOCK);
|
||||
}
|
||||
|
||||
int pthread_mutexattr_init (pthread_mutexattr_t *attr)
|
||||
{
|
||||
// Verify parameter
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
attr->type = PTHREAD_MUTEX_DEFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_destroy (pthread_mutexattr_t *attr)
|
||||
{
|
||||
// Verify parameter
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
attr->type = PTHREAD_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
*type = attr->type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return EINVAL;
|
||||
|
||||
if (type != PTHREAD_MUTEX_DEFAULT && type != PTHREAD_MUTEX_RECURSIVE)
|
||||
return EINVAL;
|
||||
|
||||
attr->type = type;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PTHREAD_MUTEX */
|
||||
#endif /* CONFIG_PTHREAD_SUPPORT */
|
115
lib/bsp/xilkernel/src/syscall/libsemaphore.c
Executable file
115
lib/bsp/xilkernel/src/syscall/libsemaphore.c
Executable file
|
@ -0,0 +1,115 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libsemaphore.c
|
||||
//! This contains system call wrapper functions for POSIX Semaphore routines
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/ksemaphore.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_SEMA
|
||||
int sem_init(sem_t* sem, int pshared, unsigned value)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, (void*)pshared, (void*)value, NULL, NULL, SC_SEM_INIT);
|
||||
}
|
||||
|
||||
int sem_trywait(sem_t* sem)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, NULL, NULL, NULL, NULL, SC_SEM_TRYWAIT);
|
||||
}
|
||||
|
||||
int sem_wait(sem_t* sem)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, NULL, NULL, NULL, NULL, SC_SEM_WAIT);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
int sem_timedwait (sem_t* sem, unsigned int ticks)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, (void*)ticks, NULL, NULL, NULL, SC_SEM_TIMED_WAIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sem_getvalue(sem_t* sem, int* sval)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, (void*)sval, NULL, NULL, NULL, SC_SEM_GETVALUE);
|
||||
}
|
||||
|
||||
int sem_post(sem_t* sem)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, NULL, NULL, NULL, NULL, SC_SEM_POST);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NAMED_SEMA
|
||||
sem_t* sem_open(const char* name, int oflag, ...)
|
||||
{
|
||||
mode_t mode;
|
||||
unsigned value;
|
||||
va_list varptr;
|
||||
|
||||
if( !(oflag & O_CREAT) ) // Other flags unsupported
|
||||
return (sem_t*)SEM_FAILED;
|
||||
|
||||
if (!(oflag & O_EXCL)) {
|
||||
|
||||
va_start( varptr, oflag );
|
||||
|
||||
mode = va_arg( varptr, mode_t );
|
||||
value = va_arg( varptr, unsigned );
|
||||
|
||||
va_end (varptr);
|
||||
}
|
||||
|
||||
return (sem_t*) make_syscall ((void*)name, (void*)oflag, (void*)mode, (void*)value, NULL, SC_SEM_OPEN);
|
||||
}
|
||||
|
||||
int sem_unlink(const char* name)
|
||||
{
|
||||
return (int) make_syscall ((void*)name, NULL, NULL, NULL, NULL, SC_SEM_UNLINK);
|
||||
}
|
||||
|
||||
int sem_close(sem_t* sem)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, NULL, NULL, NULL, NULL, SC_SEM_CLOSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
int sem_destroy(sem_t* sem)
|
||||
{
|
||||
return (int) make_syscall ((void*)sem, NULL, NULL, NULL, NULL, SC_SEM_DESTROY);
|
||||
}
|
||||
#endif /* CONFIG_SEMA */
|
65
lib/bsp/xilkernel/src/syscall/libshm.c
Executable file
65
lib/bsp/xilkernel/src/syscall/libshm.c
Executable file
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libshm.c
|
||||
//! This contains system call wrapper functions for Shared Memory.
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/kshm.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_SHM
|
||||
int shmget (key_t key, size_t size, int shmflg )
|
||||
{
|
||||
return (int) make_syscall ((void*)key, (void*)size, (void*)shmflg, NULL, NULL, SC_SHMGET);
|
||||
}
|
||||
|
||||
int shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
||||
{
|
||||
return (int) make_syscall ((void*)shmid, (void*)cmd, (void*)buf, NULL, NULL, SC_SHMCTL);
|
||||
}
|
||||
|
||||
void* shmat (int shmid, const void *shmaddr, int shmflg )
|
||||
{
|
||||
return (void*) make_syscall ((void*)shmid, (void*)shmaddr, (void*)shmflg, NULL, NULL, SC_SHMAT);
|
||||
}
|
||||
|
||||
int shmdt( const void *shmaddr )
|
||||
{
|
||||
return (int) make_syscall ((void*)shmaddr, NULL, NULL, NULL, NULL, SC_SHMDT);
|
||||
}
|
||||
#endif /* CONFIG_SHM */
|
57
lib/bsp/xilkernel/src/syscall/libtimer.c
Executable file
57
lib/bsp/xilkernel/src/syscall/libtimer.c
Executable file
|
@ -0,0 +1,57 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
//! @file libtimer.c
|
||||
//! System call wrappers for timers
|
||||
//----------------------------------------------------------------------------------------------------//
|
||||
#include <os_config.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/timer.h>
|
||||
|
||||
extern void* make_syscall (void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, int syscall_num);
|
||||
|
||||
#ifdef CONFIG_TIME
|
||||
unsigned int xget_clock_ticks (void)
|
||||
{
|
||||
return (unsigned int) make_syscall (NULL, NULL, NULL, NULL, NULL, SC_TMR_GETCLOCKTICKS);
|
||||
}
|
||||
|
||||
time_t time (time_t *timer)
|
||||
{
|
||||
return (time_t) make_syscall ((void*)timer, NULL, NULL, NULL, NULL, SC_TMR_TIME);
|
||||
}
|
||||
|
||||
unsigned sleep (unsigned ticks)
|
||||
{
|
||||
return (unsigned) make_syscall ((void*)ticks, NULL, NULL, NULL, NULL, SC_TMR_SLEEP);
|
||||
}
|
||||
#endif /* CONFIG_TIME */
|
Loading…
Add table
Reference in a new issue