ext: move libmetal to an external module
Move libmetal to be an external module and add it manifest. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
0b2bb32cb4
commit
fe0a50f812
|
@ -184,7 +184,6 @@
|
|||
/ext/hal/atmel/asf/sam/include/same70*/ @aurel32
|
||||
/ext/hal/atmel/asf/sam0/include/samr21/ @benpicco
|
||||
/ext/hal/cmsis/ @MaureenHelm @galak
|
||||
/ext/hal/libmetal/ @galak
|
||||
/ext/hal/microchip/ @franciscomunoz @albertofloyd @scottwcpg
|
||||
/ext/hal/nordic/ @carlescufi @anangl
|
||||
/ext/hal/nxp/ @MaureenHelm
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
add_subdirectory(atmel)
|
||||
add_subdirectory(cmsis)
|
||||
add_subdirectory_if_kconfig(libmetal)
|
||||
add_subdirectory(nordic)
|
||||
add_subdirectory(nxp)
|
||||
add_subdirectory(openisa)
|
||||
|
|
|
@ -16,8 +16,6 @@ source "ext/hal/altera/Kconfig"
|
|||
|
||||
source "ext/hal/cmsis/Kconfig"
|
||||
|
||||
source "ext/hal/libmetal/Kconfig"
|
||||
|
||||
source "ext/hal/microchip/Kconfig"
|
||||
|
||||
source "ext/hal/nordic/Kconfig"
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2018 Linaro Limited
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set(WITH_ZEPHYR 1)
|
||||
set(WITH_ZEPHYR_LIB 1)
|
||||
set(WITH_DOC OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DEFAULT_LOGGER OFF CACHE BOOL "" FORCE)
|
||||
|
||||
add_subdirectory(${CONFIG_LIBMETAL_SRC_PATH} libmetal)
|
|
@ -1,20 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2018 Linaro Limited
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menuconfig LIBMETAL
|
||||
bool "libmetal Support"
|
||||
help
|
||||
This option enables the libmetal HAL abstraction layer
|
||||
|
||||
if LIBMETAL
|
||||
|
||||
config LIBMETAL_SRC_PATH
|
||||
string "libmetal library source path"
|
||||
default "libmetal"
|
||||
help
|
||||
This option specifies the path to the source for the libmetal library
|
||||
|
||||
endif # LIBMETAL
|
|
@ -1,39 +0,0 @@
|
|||
libmetal
|
||||
#####################
|
||||
|
||||
Origin:
|
||||
https://github.com/OpenAMP/libmetal
|
||||
|
||||
Import instructions:
|
||||
When we import libmetal we remove the tests/ and examples/ dir to reduce
|
||||
the amount of code imported.
|
||||
|
||||
Purpose:
|
||||
HAL abstraction layer used by open-amp
|
||||
|
||||
Description:
|
||||
Libmetal provides common user APIs to access devices, handle device
|
||||
interrupts and request memory across the following operating environments:
|
||||
|
||||
* Linux user space (based on UIO and VFIO support in the kernel)
|
||||
* RTOS (with and without virtual memory)
|
||||
* Bare-metal environments
|
||||
|
||||
Dependencies:
|
||||
Depends on Zephyr itself as it utilizes Zephyr's APIs to provide an
|
||||
abstraction to open-amp.
|
||||
|
||||
URL:
|
||||
https://github.com/OpenAMP/libmetal
|
||||
|
||||
commit:
|
||||
a4f763094cb26cd8f7abdff251f57a6a802c039d
|
||||
|
||||
Maintained-by:
|
||||
External
|
||||
|
||||
License:
|
||||
BSD-3-Clause
|
||||
|
||||
License Link:
|
||||
https://github.com/OpenAMP/libmetal/blob/master/LICENSE.md
|
18
ext/hal/libmetal/libmetal/.gitignore
vendored
18
ext/hal/libmetal/libmetal/.gitignore
vendored
|
@ -1,18 +0,0 @@
|
|||
*.o
|
||||
*~
|
||||
!libs/system/zc702evk/linux/lib/*/*.a
|
||||
*.bin
|
||||
*.map
|
||||
*.out
|
||||
*.log
|
||||
*.swp
|
||||
*.swo
|
||||
*.d
|
||||
build*/
|
||||
|
||||
/tags
|
||||
/TAGS
|
||||
|
||||
# cscope files
|
||||
cscope.*
|
||||
ncscope.*
|
|
@ -1,112 +0,0 @@
|
|||
language: minimal # setting language to C will override cross-compiler and fail
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
global:
|
||||
- ZEPHYR_TOOLCHAIN_VARIANT=zephyr
|
||||
- ZEPHYR_SDK_INSTALL_DIR=/opt/zephyr-sdk
|
||||
- ZEPHYR_BASE=$TRAVIS_BUILD_DIR/deps/zephyr
|
||||
- ZEPHYR_SDK_VERSION=0.9.5
|
||||
- ZEPHYR_SDK_DOWNLOAD_FOLDER=https://github.com/zephyrproject-rtos/meta-zephyr-sdk/releases/download/$ZEPHYR_SDK_VERSION
|
||||
- ZEPHYR_SDK_SETUP_BINARY=zephyr-sdk-$ZEPHYR_SDK_VERSION-setup.run
|
||||
- ZEPHYR_SDK_DOWNLOAD_URL=$ZEPHYR_SDK_DOWNLOAD_FOLDER/$ZEPHYR_SDK_SETUP_BINARY
|
||||
- FREERTOS_ZIP_URL=https://cfhcable.dl.sourceforge.net/project/freertos/FreeRTOS/V10.0.1/FreeRTOSv10.0.1.zip
|
||||
- GCC_ARM_COMPILER_PACKAGE=gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb
|
||||
- CC=gcc-4.9
|
||||
- CXX=g++-4.9
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: linux
|
||||
env: TARGET="zephyr"
|
||||
- os: linux
|
||||
env: TARGET="linux"
|
||||
- os: linux
|
||||
env: TARGET="generic"
|
||||
- os: linux
|
||||
env: TARGET="freertos"
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $ZEPHYR_SDK_INSTALL_DIR
|
||||
- /usr/local/bin
|
||||
- $HOME/bin/cmake
|
||||
|
||||
before_install:
|
||||
- if [ ! -f $HOME/bin/cmake/cmake-3.13.1-Linux-x86_64/bin/cmake ]; then
|
||||
mkdir -p $HOME/bin/cmake && cd $HOME/bin/cmake &&
|
||||
wget https://github.com/Kitware/CMake/releases/download/v3.13.1/cmake-3.13.1-Linux-x86_64.sh &&
|
||||
yes | sh cmake-3.13.1-Linux-x86_64.sh | cat &&
|
||||
cd -;
|
||||
fi &&
|
||||
export PATH=$HOME/bin/cmake/cmake-3.13.1-Linux-x86_64/bin:$PATH
|
||||
- if [[ "$TARGET" == "zephyr" ]]; then
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test &&
|
||||
sudo apt-get update -qq &&
|
||||
sudo apt-get install libc6-dev-i386 make gperf gcc g++ python3-ply python3-yaml python3-pip device-tree-compiler ncurses-dev uglifyjs -qq &&
|
||||
sudo pip3 install pyelftools;
|
||||
fi
|
||||
- if [[ "$TARGET" == "linux" ]]; then
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test &&
|
||||
sudo apt-get update -qq &&
|
||||
sudo apt-get install libsysfs-dev libhugetlbfs-dev make gcc-4.9;
|
||||
fi
|
||||
# This is to kick start CI on generic platform. Will need to have a proper way to get the required packages
|
||||
- if [[ "$TARGET" == "generic" || "$TARGET" == "freertos" ]]; then
|
||||
wget http://ppa.launchpad.net/team-gcc-arm-embedded/ppa/ubuntu/pool/main/g/gcc-arm-none-eabi/${GCC_ARM_COMPILER_PACKAGE} &&
|
||||
sudo dpkg -i ${GCC_ARM_COMPILER_PACKAGE};
|
||||
fi
|
||||
- if [[ "$TARGET" == "freertos" ]]; then
|
||||
wget $FREERTOS_ZIP_URL &&
|
||||
pwd && ls &&
|
||||
unzip FreeRTOSv10.0.1.zip > /dev/null;
|
||||
fi
|
||||
|
||||
install: >
|
||||
if [[ "$TARGET" == "zephyr" && "$(cat $ZEPHYR_SDK_INSTALL_DIR/sdk_version)" != "$ZEPHYR_SDK_VERSION" ]]; then
|
||||
wget $ZEPHYR_SDK_DOWNLOAD_URL &&
|
||||
chmod +x $ZEPHYR_SDK_SETUP_BINARY &&
|
||||
rm -rf $ZEPHYR_SDK_INSTALL_DIR &&
|
||||
./$ZEPHYR_SDK_SETUP_BINARY --quiet -- -y -d $ZEPHYR_SDK_INSTALL_DIR > /dev/null;
|
||||
fi
|
||||
|
||||
before_script: >
|
||||
if [[ "$TARGET" == "zephyr" ]]; then
|
||||
cd .. &&
|
||||
git clone --depth=1 https://github.com/zephyrproject-rtos/zephyr.git &&
|
||||
cd zephyr &&
|
||||
source zephyr-env.sh;
|
||||
fi
|
||||
|
||||
script:
|
||||
- if [[ "$TARGET" == "zephyr" ]]; then
|
||||
mkdir -p ../libmetal/build-zephyr &&
|
||||
cd ../libmetal/build-zephyr &&
|
||||
cmake .. -DWITH_ZEPHYR=on -DBOARD=qemu_cortex_m3 &&
|
||||
make VERBOSE=1;
|
||||
fi
|
||||
- if [[ "$TARGET" == "linux" ]]; then
|
||||
mkdir -p build-linux &&
|
||||
cd build-linux &&
|
||||
cmake .. -DWITH_TESTS_EXEC=on &&
|
||||
make VERBOSE=1 all test;
|
||||
fi
|
||||
- if [[ "$TARGET" == "generic" ]]; then
|
||||
mkdir -p build-generic &&
|
||||
cd build-generic &&
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=template-generic &&
|
||||
make VERBOSE=1;
|
||||
fi
|
||||
- if [[ "$TARGET" == "freertos" ]]; then
|
||||
mkdir -p build-freertos &&
|
||||
cd build-freertos &&
|
||||
export &&
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=template-freertos -DCMAKE_C_FLAGS="-I$PWD/../FreeRTOSv10.0.1/FreeRTOS/Source/include/ -I$PWD/../FreeRTOSv10.0.1/FreeRTOS/Demo/CORTEX_STM32F107_GCC_Rowley -I$PWD/../FreeRTOSv10.0.1/FreeRTOS/Source/portable/GCC/ARM_CM3" &&
|
||||
make VERBOSE=1;
|
||||
fi
|
|
@ -1,40 +0,0 @@
|
|||
cmake_minimum_required (VERSION 2.6)
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif()
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/platforms")
|
||||
|
||||
include (syscheck)
|
||||
project (metal C)
|
||||
|
||||
include (CheckIncludeFiles)
|
||||
include (CheckCSourceCompiles)
|
||||
include (collect)
|
||||
include (options)
|
||||
include (depends)
|
||||
|
||||
foreach(_inc_path ${CMAKE_INCLUDE_PATH})
|
||||
collect (PROJECT_INC_DIRS "${_inc_path}")
|
||||
endforeach()
|
||||
|
||||
enable_testing ()
|
||||
|
||||
add_subdirectory (lib)
|
||||
|
||||
if (WITH_TESTS)
|
||||
add_subdirectory (test)
|
||||
endif (WITH_TESTS)
|
||||
|
||||
if (WITH_DOC)
|
||||
add_subdirectory (doc)
|
||||
endif (WITH_DOC)
|
||||
|
||||
if (WITH_EXAMPLES)
|
||||
add_subdirectory (examples)
|
||||
endif (WITH_EXAMPLES)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,41 +0,0 @@
|
|||
Software License Agreement (BSD License)
|
||||
========================================
|
||||
|
||||
Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Xilinx nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Notes
|
||||
=========================================
|
||||
Use the following tag instead of the full license text in the individual files:
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
This enables machine processing of license information based on the SPDX
|
||||
License Identifiers that are here available: http://spdx.org/licenses/
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# libmetal Maintainers
|
||||
|
||||
libmetal project is maintained by the OpenAMP open source community.
|
||||
Everyone is encouraged to submit issues and changes to improve libmetal.
|
||||
|
||||
The intention of this file is to provide a set of names that developers can
|
||||
consult when they have a question about OpenAMP and to provide a a set of
|
||||
names to be CC'd when submitting a patch.
|
||||
|
||||
## Project Administration
|
||||
Wendy Liang <wendy.liang@xilinx.com>
|
||||
|
||||
### All patches CC here
|
||||
open-amp@googlegroups.com
|
||||
|
||||
## Machines
|
||||
### Xilinx Platform - Zynq-7000
|
||||
Wendy Liang <wendy.liang@xilinx.com>
|
||||
|
||||
### Xilinx Platform - Zynq UltraScale+ MPSoC
|
||||
Wendy Liang <wendy.liang@xilinx.com>
|
|
@ -1,220 +0,0 @@
|
|||
# libmetal
|
||||
|
||||
## Overview
|
||||
|
||||
Libmetal provides common user APIs to access devices, handle device interrupts
|
||||
and request memory across the following operating environments:
|
||||
* Linux user space (based on UIO and VFIO support in the kernel)
|
||||
* RTOS (with and without virtual memory)
|
||||
* Bare-metal environments
|
||||
|
||||
## Build Steps
|
||||
|
||||
### Building for Linux Host
|
||||
```
|
||||
$ git clone https://github.com/OpenAMP/libmetal.git
|
||||
$ mkdir -p libmetal/<build directory>
|
||||
$ cd libmetal/<build directory>
|
||||
$ cmake ..
|
||||
$ make VERBOSE=1 DESTDIR=<libmetal install location> install
|
||||
```
|
||||
|
||||
### Cross Compiling for Linux Target
|
||||
Use [meta-openamp](https://github.com/openamp/meta-openamp) to build
|
||||
libmetal library.
|
||||
Use package `libmetal` in your yocto config file.
|
||||
|
||||
### Building for Baremetal
|
||||
|
||||
To build on baremetal, you will need to provide a toolchain file. Here is an
|
||||
example toolchain file:
|
||||
```
|
||||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "zynqmp_r5" CACHE STRING "")
|
||||
|
||||
set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "")
|
||||
set (CMAKE_C_FLAGS "-mfloat-abi=soft -mcpu=cortex-r5 -Wall -Werror -Wextra \
|
||||
-flto -Os -I/ws/xsdk/r5_0_bsp/psu_cortexr5_0/include" CACHE STRING "")
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
|
||||
SET(CMAKE_AR "gcc-ar" CACHE STRING "")
|
||||
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
SET(CMAKE_C_ARCHIVE_FINISH true)
|
||||
|
||||
include (cross-generic-gcc)
|
||||
```
|
||||
* Note: other toolchain files can be found in the `cmake/platforms/` directory.
|
||||
* Compile with your toolchain file.
|
||||
```
|
||||
$ mkdir -p build-libmetal
|
||||
$ cd build-libmetal
|
||||
$ cmake <libmetal_source> -DCMAKE_TOOLCHAIN_FILE=<toolchain_file>
|
||||
$ make VERBOSE=1 DESTDIR=<libmetal_install> install
|
||||
```
|
||||
|
||||
### Building for Zephyr
|
||||
As Zephyr uses CMake, we build libmetal library and test application as
|
||||
targets of Zephyr CMake project. Here is how to build libmetal for Zephyr:
|
||||
```
|
||||
$ export ZEPHYR_GCC_VARIANT=zephyr
|
||||
$ export ZEPHYR_SDK_INSTALL_DIR=<where Zephyr SDK is installed>
|
||||
$ source <git_clone_zephyr_project_source_root>/zephyr-env.sh
|
||||
|
||||
$ cmake <libmetal_source_root> -DWITH_ZEPHYR=on -DBOARD=qemu_cortex_m3 \
|
||||
[-DWITH_TESTS=on]
|
||||
$ make VERBOSE=1 all
|
||||
# If we have turned on tests with "-DWITH_TESTS=on" when we run cmake,
|
||||
# we launch libmetal test on Zephyr QEMU platform as follows:
|
||||
$ make VERBOSE=1 run
|
||||
```
|
||||
|
||||
## Interfaces
|
||||
|
||||
The following subsections give an overview of interfaces provided by libmetal.
|
||||
|
||||
### Platform and OS Independent Utilities
|
||||
|
||||
These interfaces do not need to be ported across to new operating systems.
|
||||
|
||||
#### I/O
|
||||
|
||||
The libmetal I/O region abstraction provides access to memory mapped I/O and
|
||||
shared memory regions. This includes:
|
||||
* primitives to read and write memory with ordering constraints, and
|
||||
* ability to translate between physical and virtual addressing on systems
|
||||
that support virtual memory.
|
||||
|
||||
#### Log
|
||||
|
||||
The libmetal logging interface is used to plug log messages generated by
|
||||
libmetal into application specific logging mechanisms (e.g. syslog). This
|
||||
also provides basic message prioritization and filtering mechanisms.
|
||||
|
||||
#### List
|
||||
|
||||
This is a simple doubly linked list implementation used internally within
|
||||
libmetal, and also available for application use.
|
||||
|
||||
#### Other Utilities
|
||||
|
||||
The following utilities are provided in lib/utilities.h:
|
||||
* Min/max, round up/down, etc.
|
||||
* Bitmap operations
|
||||
* Helper to compute container structure pointers
|
||||
* ... and more ...
|
||||
|
||||
#### Version
|
||||
|
||||
The libmetal version interface allows user to get the version of the library.
|
||||
|
||||
### Top Level Interfaces
|
||||
|
||||
The users will need to call two top level interfaces to use libmetal APIs:
|
||||
* metal_init - initialize the libmetal resource
|
||||
* metal_finish - release libmetal resource
|
||||
|
||||
Each system needs to have their own implementation inside libmetal for these
|
||||
two APIs to call:
|
||||
* metal_sys_init
|
||||
* metal_sys_finish
|
||||
|
||||
For the current release, libmetal provides Linux userspace and bare-metal
|
||||
implementation for metal_sys_init and metal_sys_finish.
|
||||
|
||||
For Linux userspace, metal_sys_init sets up a table for available shared pages,
|
||||
checks whether UIO/VFIO drivers are avail, and starts interrupt handling
|
||||
thread.
|
||||
|
||||
For bare-metal, metal_sys_init and metal_sys_finish just returns.
|
||||
|
||||
### Atomics
|
||||
|
||||
The libmetal atomic operations API is consistent with the C11/C++11 stdatomics
|
||||
interface. The stdatomics interface is commonly provided by recent toolchains
|
||||
including GCC and LLVM/Clang. When porting to a different toolchain, it may be
|
||||
necessary to provide an stdatomic compatible implementation if the toolchain
|
||||
does not already provide one.
|
||||
|
||||
### Alloc
|
||||
|
||||
libmetal provides memory allocation and release APIs.
|
||||
|
||||
### Locking
|
||||
|
||||
libmetal provides the following locking APIs.
|
||||
|
||||
#### Mutex
|
||||
|
||||
libmetal has a generic mutex implementation which is a busy wait. It is
|
||||
recommended to have OS specific implementation for mutex.
|
||||
|
||||
The Linux userspace mutex implementation uses futex to wait for the lock
|
||||
and wakeup a waiter.
|
||||
|
||||
#### Condition Variable
|
||||
libmetal condition variable APIs provide "wait" for user applications to wait
|
||||
on some condition to be met, and "signal" to indicate a particular even occurs.
|
||||
|
||||
#### Spinlock
|
||||
libmetal spinlock APIs provides busy waiting mechanism to acquire a lock.
|
||||
|
||||
### Shmem
|
||||
|
||||
libmetal has a generic static shared memory implementation. If your OS has a
|
||||
global shared memory allocation, you will need to port it for the OS.
|
||||
|
||||
The Linux userspace shmem implementation uses libhugetlbfs to support huge page
|
||||
sizes.
|
||||
|
||||
### Bus and Device Abstraction
|
||||
|
||||
libmetal has a static generic implementation. If your OS has a driver model
|
||||
implementation, you will need to port it for the OS.
|
||||
|
||||
The Linux userspace abstraction binds the devices to UIO or VFIO driver.
|
||||
The user applications specify which device to use, e.g. bus "platform" bus,
|
||||
device "f8000000.slcr", and then the abstraction will check if platform UIO
|
||||
driver or platform VFIO driver is there. If platform VFIO driver exists,
|
||||
it will bind the device to the platform VFIO driver, otherwise, if UIO driver
|
||||
exists, it will bind the device to the platform UIO driver.
|
||||
|
||||
The VFIO support is not yet implemented.
|
||||
|
||||
### Interrupt
|
||||
|
||||
libmetal provides APIs to register an interrupt, disable interrupts and restore
|
||||
interrupts.
|
||||
|
||||
The Linux userspace implementation will use a thread to call select() function
|
||||
to listen to the file descriptors of the devices to see if there is an interrupt
|
||||
triggered. If there is an interrupt triggered, it will call the interrupt
|
||||
handler registered by the user application.
|
||||
|
||||
### Cache
|
||||
|
||||
libmetal provides APIs to flush and invalidate caches.
|
||||
|
||||
The cache APIs for Linux userspace are empty functions for now as cache
|
||||
operations system calls are not avaiable for all architectures.
|
||||
|
||||
### DMA
|
||||
|
||||
libmetal DMA APIs provide DMA map and unmap implementation.
|
||||
|
||||
After calling DMA map, the DMA device will own the memory.
|
||||
After calling DMA unmap, the cpu will own the memory.
|
||||
|
||||
For Linux userspace, it only supports to use UIO device memory as DMA
|
||||
memory for this release.
|
||||
|
||||
### Time
|
||||
libmetal time APIs provide getting timestamp implementation.
|
||||
|
||||
### Sleep
|
||||
libmetal sleep APIs provide getting delay execution implementation.
|
||||
|
||||
### Compiler
|
||||
|
||||
This API is for compiler dependent functions. For this release, there is only
|
||||
a GCC implementation, and compiler specific code is limited to atomic
|
||||
operations.
|
|
@ -1,36 +0,0 @@
|
|||
function (collector_create name base)
|
||||
set_property (GLOBAL PROPERTY "COLLECT_${name}_LIST")
|
||||
set_property (GLOBAL PROPERTY "COLLECT_${name}_BASE" "${base}")
|
||||
endfunction (collector_create)
|
||||
|
||||
function (collector_list var name)
|
||||
get_property (_list GLOBAL PROPERTY "COLLECT_${name}_LIST")
|
||||
set (${var} "${_list}" PARENT_SCOPE)
|
||||
endfunction (collector_list)
|
||||
|
||||
function (collector_base var name)
|
||||
get_property (_base GLOBAL PROPERTY "COLLECT_${name}_BASE")
|
||||
set (${var} "${_base}" PARENT_SCOPE)
|
||||
endfunction (collector_base)
|
||||
|
||||
function (collect name)
|
||||
collector_base (_base ${name})
|
||||
string(COMPARE NOTEQUAL "${_base}" "" _is_rel)
|
||||
set (_list)
|
||||
foreach (s IN LISTS ARGN)
|
||||
if (_is_rel)
|
||||
get_filename_component (s "${s}" ABSOLUTE)
|
||||
file (RELATIVE_PATH s "${_base}" "${s}")
|
||||
endif (_is_rel)
|
||||
list (APPEND _list "${s}")
|
||||
endforeach ()
|
||||
set_property (GLOBAL APPEND PROPERTY "COLLECT_${name}_LIST" "${_list}")
|
||||
endfunction (collect)
|
||||
|
||||
# Create global collectors
|
||||
collector_create (PROJECT_INC_DIRS "")
|
||||
collector_create (PROJECT_LIB_DIRS "")
|
||||
collector_create (PROJECT_LIB_DEPS "")
|
||||
collector_create (PROJECT_HDR_TESTS "")
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,38 +0,0 @@
|
|||
if (WITH_DOC)
|
||||
find_package (Doxygen)
|
||||
endif (WITH_DOC)
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
|
||||
check_include_files (stdatomic.h HAVE_STDATOMIC_H)
|
||||
check_include_files (linux/futex.h HAVE_FUTEX_H)
|
||||
|
||||
find_package (HugeTLBFS)
|
||||
if (HUGETLBFS_FOUND)
|
||||
collect (PROJECT_INC_DIRS "${HUGETLBFS_INCLUDE_DIR}")
|
||||
collect (PROJECT_LIB_DEPS "${HUGETLBFS_LIBRARIES}")
|
||||
add_definitions(-DHAVE_HUGETLBFS_H)
|
||||
endif(HUGETLBFS_FOUND)
|
||||
|
||||
find_package (LibSysFS REQUIRED)
|
||||
collect (PROJECT_INC_DIRS "${LIBSYSFS_INCLUDE_DIR}")
|
||||
collect (PROJECT_LIB_DEPS "${LIBSYSFS_LIBRARIES}")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
collect (PROJECT_LIB_DEPS "${CMAKE_THREAD_LIBS_INIT}")
|
||||
|
||||
find_package(LibRt REQUIRED)
|
||||
collect (PROJECT_LIB_DEPS "${LIBRT_LIBRARIES}")
|
||||
|
||||
else ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
|
||||
# TODO: fix for find_path() to detect stdatomic.h
|
||||
# find_path (HAVE_STDATOMIC_H stdatomic.h)
|
||||
set (_saved_cmake_required_flags ${CMAKE_REQUIRED_FLAGS})
|
||||
set (CMAKE_REQUIRED_FLAGS "-c" CACHE STRING "")
|
||||
check_include_files (stdatomic.h HAVE_STDATOMIC_H)
|
||||
set (CMAKE_REQUIRED_FLAGS ${_saved_cmake_required_flags})
|
||||
|
||||
endif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,34 +0,0 @@
|
|||
# FindHugeTLBFS
|
||||
# --------
|
||||
#
|
||||
# Find HugeTLBFS
|
||||
#
|
||||
# Find the native HugeTLBFS includes and library This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# HUGETLBFS_INCLUDE_DIR, where to find hugetlbfs.h, etc.
|
||||
# HUGETLBFS_LIBRARIES, the libraries needed to use HugeTLBFS.
|
||||
# HUGETLBFS_FOUND, If false, do not try to use HugeTLBFS.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# HUGETLBFS_LIBRARY, where to find the HugeTLBFS library.
|
||||
|
||||
find_path (HUGETLBFS_INCLUDE_DIR hugetlbfs.h)
|
||||
|
||||
set (HUGETLBFS_NAMES ${HUGETLBFS_NAMES} hugetlbfs)
|
||||
find_library (HUGETLBFS_LIBRARY NAMES ${HUGETLBFS_NAMES})
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set HUGETLBFS_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include (FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS (HUGETLBFS DEFAULT_MSG HUGETLBFS_LIBRARY HUGETLBFS_INCLUDE_DIR)
|
||||
|
||||
if (HUGETLBFS_FOUND)
|
||||
set (HUGETLBFS_LIBRARIES ${HUGETLBFS_LIBRARY})
|
||||
endif (HUGETLBFS_FOUND)
|
||||
|
||||
mark_as_advanced (HUGETLBFS_LIBRARY HUGETLBFS_INCLUDE_DIR)
|
|
@ -1,46 +0,0 @@
|
|||
#.rst:
|
||||
# FindLibRt
|
||||
# --------
|
||||
#
|
||||
# Find the native realtime includes and library.
|
||||
#
|
||||
# IMPORTED Targets
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module defines :prop_tgt:`IMPORTED` target ``LIBRT::LIBRT``, if
|
||||
# LIBRT has been found.
|
||||
#
|
||||
# Result Variables
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module defines the following variables:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LIBRT_INCLUDE_DIRS - where to find time.h, etc.
|
||||
# LIBRT_LIBRARIES - List of libraries when using librt.
|
||||
# LIBRT_FOUND - True if realtime library found.
|
||||
#
|
||||
# Hints
|
||||
# ^^^^^
|
||||
#
|
||||
# A user may set ``LIBRT_ROOT`` to a realtime installation root to tell this
|
||||
# module where to look.
|
||||
|
||||
find_path(LIBRT_INCLUDE_DIRS
|
||||
NAMES time.h
|
||||
PATHS ${LIBRT_ROOT}/include/
|
||||
)
|
||||
find_library(LIBRT_LIBRARIES rt)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LibRt DEFAULT_MSG LIBRT_LIBRARIES LIBRT_INCLUDE_DIRS)
|
||||
mark_as_advanced(LIBRT_INCLUDE_DIRS LIBRT_LIBRARIES)
|
||||
|
||||
if(LIBRT_FOUND)
|
||||
if(NOT TARGET LIBRT::LIBRT)
|
||||
add_library(LIBRT::LIBRT UNKNOWN IMPORTED)
|
||||
set_target_properties(LIBRT::LIBRT PROPERTIES
|
||||
IMPORTED_LOCATION "${LIBRT_LIBRARIES}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBRT_INCLUDE_DIRS}")
|
||||
endif()
|
||||
endif()
|
|
@ -1,34 +0,0 @@
|
|||
# FindLibSysFS
|
||||
# --------
|
||||
#
|
||||
# Find LibSysFS
|
||||
#
|
||||
# Find the native LibSysFS includes and library This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LIBSYSFS_INCLUDE_DIR, where to find libsysfs.h, etc.
|
||||
# LIBSYSFS_LIBRARIES, the libraries needed to use LibSysFS.
|
||||
# LIBSYSFS_FOUND, If false, do not try to use LibSysFS.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LIBSYSFS_LIBRARY, where to find the LibSysFS library.
|
||||
|
||||
find_path (LIBSYSFS_INCLUDE_DIR sysfs/libsysfs.h)
|
||||
|
||||
set (LIBSYSFS_NAMES ${LIBSYSFS_NAMES} sysfs)
|
||||
find_library (LIBSYSFS_LIBRARY NAMES ${LIBSYSFS_NAMES})
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBSYSFS_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
include (FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS (LIBSYSFS DEFAULT_MSG LIBSYSFS_LIBRARY LIBSYSFS_INCLUDE_DIR)
|
||||
|
||||
if (LIBSYSFS_FOUND)
|
||||
set (LIBSYSFS_LIBRARIES ${LIBSYSFS_LIBRARY})
|
||||
endif (LIBSYSFS_FOUND)
|
||||
|
||||
mark_as_advanced (LIBSYSFS_LIBRARY LIBSYSFS_INCLUDE_DIR)
|
|
@ -1,63 +0,0 @@
|
|||
set (PROJECT_VER_MAJOR 0)
|
||||
set (PROJECT_VER_MINOR 1)
|
||||
set (PROJECT_VER_PATCH 0)
|
||||
set (PROJECT_VER 0.1.0)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Debug)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
message ("-- Build type: ${CMAKE_BUILD_TYPE}")
|
||||
|
||||
if (NOT CMAKE_INSTALL_LIBDIR)
|
||||
set (CMAKE_INSTALL_LIBDIR "lib")
|
||||
endif (NOT CMAKE_INSTALL_LIBDIR)
|
||||
|
||||
if (NOT CMAKE_INSTALL_BINDIR)
|
||||
set (CMAKE_INSTALL_BINDIR "bin")
|
||||
endif (NOT CMAKE_INSTALL_BINDIR)
|
||||
|
||||
set (_host "${CMAKE_HOST_SYSTEM_NAME}/${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
message ("-- Host: ${_host}")
|
||||
|
||||
set (_target "${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message ("-- Target: ${_target}")
|
||||
|
||||
if (NOT DEFINED MACHINE)
|
||||
set (MACHINE "Generic")
|
||||
endif (NOT DEFINED MACHINE)
|
||||
message ("-- Machine: ${MACHINE}")
|
||||
|
||||
# handle if '-' in machine name
|
||||
string (REPLACE "-" "_" MACHINE ${MACHINE})
|
||||
|
||||
if (NOT DEFINED PROJECT_SYSTEM)
|
||||
string (TOLOWER ${CMAKE_SYSTEM_NAME} PROJECT_SYSTEM)
|
||||
string (TOUPPER ${CMAKE_SYSTEM_NAME} PROJECT_SYSTEM_UPPER)
|
||||
endif (NOT DEFINED PROJECT_SYSTEM)
|
||||
|
||||
string (TOLOWER ${CMAKE_SYSTEM_PROCESSOR} PROJECT_PROCESSOR)
|
||||
string (TOUPPER ${CMAKE_SYSTEM_PROCESSOR} PROJECT_PROCESSOR_UPPER)
|
||||
string (TOLOWER ${MACHINE} PROJECT_MACHINE)
|
||||
string (TOUPPER ${MACHINE} PROJECT_MACHINE_UPPER)
|
||||
|
||||
option (WITH_STATIC_LIB "Build with a static library" ON)
|
||||
|
||||
if ("${PROJECT_SYSTEM}" STREQUAL "linux")
|
||||
option (WITH_SHARED_LIB "Build with a shared library" ON)
|
||||
option (WITH_TESTS "Install test applications" ON)
|
||||
endif ("${PROJECT_SYSTEM}" STREQUAL "linux")
|
||||
|
||||
if (WITH_TESTS AND (${_host} STREQUAL ${_target}))
|
||||
option (WITH_TESTS_EXEC "Run test applications during build" ON)
|
||||
endif (WITH_TESTS AND (${_host} STREQUAL ${_target}))
|
||||
|
||||
if (WITH_ZEPHYR)
|
||||
option (WITH_ZEPHYR_LIB "Build libmetal as a zephyr library" OFF)
|
||||
endif (WITH_ZEPHYR)
|
||||
|
||||
option (WITH_DEFAULT_LOGGER "Build with default logger" ON)
|
||||
|
||||
option (WITH_DOC "Build with documentation" ON)
|
||||
|
||||
set (PROJECT_EC_FLAGS "-Wall -Werror -Wextra" CACHE STRING "")
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,6 +0,0 @@
|
|||
# cmake 3.3.2 does not know CMAKE_SYSTEM_NAME=FreeRTOS, we set it to Generic
|
||||
include (cross-generic-gcc)
|
||||
string (TOLOWER "FreeRTOS" PROJECT_SYSTEM)
|
||||
string (TOUPPER "FreeRTOS" PROJECT_SYSTEM_UPPER)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,10 +0,0 @@
|
|||
set (CMAKE_SYSTEM_NAME "Generic" CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER CACHE STRING "")
|
||||
|
||||
include (CMakeForceCompiler)
|
||||
CMAKE_FORCE_C_COMPILER ("${CROSS_PREFIX}gcc" GNU)
|
||||
CMAKE_FORCE_CXX_COMPILER ("${CROSS_PREFIX}g++" GNU)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,10 +0,0 @@
|
|||
set (CMAKE_SYSTEM_NAME "Generic" CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER CACHE STRING "")
|
||||
|
||||
include (CMakeForceCompiler)
|
||||
CMAKE_FORCE_C_COMPILER ("icc${CROSS_SUFFIX}" IAR)
|
||||
CMAKE_FORCE_CXX_COMPILER ("icc${CROSS_SUFFIX} --eec++" IAR)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,8 +0,0 @@
|
|||
set (CMAKE_SYSTEM_NAME "Linux" CACHE STRING "")
|
||||
set (CMAKE_C_COMPILER "${CROSS_PREFIX}gcc" CACHE STRING "")
|
||||
set (CMAKE_CXX_COMPILER "${CROSS_PREFIX}g++" CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER CACHE STRING "")
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER CACHE STRING "")
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,7 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "microblaze" CACHE STRING "")
|
||||
set (MACHINE "microblaze_generic" CACHE STRING "")
|
||||
set (CROSS_PREFIX "mb-" CACHE STRING "")
|
||||
# These flags are for a demo. If microblaze is changed, the flags need to be changed too.
|
||||
set (CMAKE_C_FLAGS "-mlittle-endian -mxl-barrel-shift -mxl-pattern-compare \
|
||||
-mcpu=v10.0 -mno-xl-soft-mul" CACHE STRING "")
|
||||
include (cross-generic-gcc)
|
|
@ -1,12 +0,0 @@
|
|||
# Modify to match your needs. These setttings can also be overridden at the
|
||||
# command line. (eg. cmake -DCMAKE_C_FLAGS="-O3")
|
||||
|
||||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "template" CACHE STRING "")
|
||||
set (CROSS_PREFIX "arm-none-eabi-" CACHE STRING "")
|
||||
|
||||
set (CMAKE_C_FLAGS "" CACHE STRING "")
|
||||
|
||||
include (cross-freertos-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,12 +0,0 @@
|
|||
# Modify to match your needs. These setttings can also be overridden at the
|
||||
# command line. (eg. cmake -DCMAKE_C_FLAGS="-O3")
|
||||
|
||||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "template" CACHE STRING "")
|
||||
set (CROSS_PREFIX "arm-none-eabi-" CACHE STRING "")
|
||||
|
||||
set (CMAKE_C_FLAGS "" CACHE STRING "")
|
||||
|
||||
include (cross-generic-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,9 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "zynq7" CACHE STRING "")
|
||||
set (CROSS_PREFIX "arm-none-eabi-" CACHE STRING "")
|
||||
|
||||
set (CMAKE_C_FLAGS "-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" CACHE STRING "")
|
||||
|
||||
include (cross-freertos-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,5 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (CROSS_SUFFIX "arm" CACHE STRING "")
|
||||
include (cross-generic-iar)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,9 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "zynq7" CACHE STRING "")
|
||||
set (CROSS_PREFIX "arm-none-eabi-" CACHE STRING "")
|
||||
|
||||
set (CMAKE_C_FLAGS "-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard" CACHE STRING "")
|
||||
|
||||
include (cross-generic-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,5 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (CROSS_PREFIX "arm-xilinx-linux-gnueabi-" CACHE STRING "")
|
||||
include (cross-linux-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,8 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "aarch64" CACHE STRING "")
|
||||
set (MACHINE "zynqmp_a53" CACHE STRING "")
|
||||
set (CROSS_PREFIX "aarch64-none-elf-" CACHE STRING "")
|
||||
set (CMAKE_C_FLAGS "" CACHE STRING "")
|
||||
|
||||
include (cross-freertos-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,8 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "aarch64" CACHE STRING "")
|
||||
set (MACHINE "zynqmp_a53" CACHE STRING "")
|
||||
set (CROSS_PREFIX "aarch64-none-elf-" CACHE STRING "")
|
||||
set (CMAKE_C_FLAGS "" CACHE STRING "")
|
||||
|
||||
include (cross-generic-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,5 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "aarch64" CACHE STRING "")
|
||||
set (CROSS_PREFIX "aarch64-linux-gnu-" CACHE STRING "")
|
||||
include (cross-linux-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,8 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "zynqmp_r5" CACHE STRING "")
|
||||
set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "")
|
||||
set (CMAKE_C_FLAGS "-mfloat-abi=soft -mcpu=cortex-r5" CACHE STRING "")
|
||||
|
||||
include (cross-freertos-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,10 +0,0 @@
|
|||
set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "")
|
||||
set (MACHINE "zynqmp_r5" CACHE STRING "")
|
||||
set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "")
|
||||
|
||||
# Xilinx SDK version earlier than 2017.2 use mfloat-abi=soft by default to generat libxil
|
||||
set (CMAKE_C_FLAGS "-mfloat-abi=hard -mfpu=vfpv3-d16 -mcpu=cortex-r5" CACHE STRING "")
|
||||
|
||||
include (cross-generic-gcc)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,13 +0,0 @@
|
|||
# use "Generic" as CMAKE_SYSTEM_NAME
|
||||
|
||||
if (WITH_ZEPHYR)
|
||||
set (CMAKE_SYSTEM_NAME "Generic" CACHE STRING "")
|
||||
string (TOLOWER "Zephyr" PROJECT_SYSTEM)
|
||||
string (TOUPPER "Zephyr" PROJECT_SYSTEM_UPPER)
|
||||
if (NOT WITH_ZEPHYR_LIB)
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
endif()
|
||||
if (CONFIG_CPU_CORTEX_M)
|
||||
set (MACHINE "cortexm" CACHE STRING "")
|
||||
endif (CONFIG_CPU_CORTEX_M)
|
||||
endif (WITH_ZEPHYR)
|
|
@ -1,19 +0,0 @@
|
|||
if (DOXYGEN_FOUND)
|
||||
|
||||
configure_file (Doxyfile.in Doxyfile @ONLY)
|
||||
|
||||
add_custom_target (doc ALL
|
||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
|
||||
DESTINATION share/doc/${PROJECT_NAME})
|
||||
install (FILES ${PROJECT_SOURCE_DIR}/README.md
|
||||
DESTINATION share/doc/${PROJECT_NAME})
|
||||
install (FILES ${PROJECT_SOURCE_DIR}/LICENSE.md
|
||||
DESTINATION share/doc/${PROJECT_NAME})
|
||||
|
||||
endif (DOXYGEN_FOUND)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
File diff suppressed because it is too large
Load diff
|
@ -1,105 +0,0 @@
|
|||
collector_create (PROJECT_LIB_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
collector_create (PROJECT_LIB_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
collect (PROJECT_LIB_DIRS "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
collect (PROJECT_INC_DIRS "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||
|
||||
collect (PROJECT_LIB_HEADERS alloc.h)
|
||||
collect (PROJECT_LIB_HEADERS assert.h)
|
||||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS cache.h)
|
||||
collect (PROJECT_LIB_HEADERS compiler.h)
|
||||
collect (PROJECT_LIB_HEADERS condition.h)
|
||||
collect (PROJECT_LIB_HEADERS config.h)
|
||||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
collect (PROJECT_LIB_HEADERS device.h)
|
||||
collect (PROJECT_LIB_HEADERS dma.h)
|
||||
collect (PROJECT_LIB_HEADERS io.h)
|
||||
collect (PROJECT_LIB_HEADERS irq.h)
|
||||
collect (PROJECT_LIB_HEADERS irq_controller.h)
|
||||
collect (PROJECT_LIB_HEADERS list.h)
|
||||
collect (PROJECT_LIB_HEADERS log.h)
|
||||
collect (PROJECT_LIB_HEADERS mutex.h)
|
||||
collect (PROJECT_LIB_HEADERS shmem.h)
|
||||
collect (PROJECT_LIB_HEADERS sleep.h)
|
||||
collect (PROJECT_LIB_HEADERS softirq.h)
|
||||
collect (PROJECT_LIB_HEADERS spinlock.h)
|
||||
collect (PROJECT_LIB_HEADERS sys.h)
|
||||
collect (PROJECT_LIB_HEADERS time.h)
|
||||
collect (PROJECT_LIB_HEADERS utilities.h)
|
||||
collect (PROJECT_LIB_HEADERS version.h)
|
||||
|
||||
collect (PROJECT_LIB_SOURCES dma.c)
|
||||
collect (PROJECT_LIB_SOURCES device.c)
|
||||
collect (PROJECT_LIB_SOURCES init.c)
|
||||
collect (PROJECT_LIB_SOURCES io.c)
|
||||
collect (PROJECT_LIB_SOURCES irq.c)
|
||||
collect (PROJECT_LIB_SOURCES log.c)
|
||||
collect (PROJECT_LIB_SOURCES shmem.c)
|
||||
collect (PROJECT_LIB_SOURCES softirq.c)
|
||||
collect (PROJECT_LIB_SOURCES version.c)
|
||||
|
||||
add_subdirectory (compiler)
|
||||
add_subdirectory (processor)
|
||||
add_subdirectory (system)
|
||||
|
||||
collector_list (_inc_dirs PROJECT_INC_DIRS)
|
||||
collector_list (_sources PROJECT_LIB_SOURCES)
|
||||
collector_list (_headers PROJECT_LIB_HEADERS)
|
||||
collector_list (_deps PROJECT_LIB_DEPS)
|
||||
|
||||
foreach (f ${_headers})
|
||||
configure_file (${f} include/${PROJECT_NAME}/${f} @ONLY)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/${f}
|
||||
DESTINATION include RENAME ${PROJECT_NAME}/${f})
|
||||
if (${f} MATCHES "^[^/]*\\.h")
|
||||
collect (PROJECT_HDR_TESTS "metal/${f}")
|
||||
endif (${f} MATCHES "^[^/]*\\.h")
|
||||
endforeach (f)
|
||||
|
||||
include_directories (${_inc_dirs})
|
||||
add_definitions (-DMETAL_INTERNAL)
|
||||
|
||||
if (WITH_DEFAULT_LOGGER)
|
||||
add_definitions (-DDEFAULT_LOGGER_ON)
|
||||
endif (WITH_DEFAULT_LOGGER)
|
||||
|
||||
if (WITH_ZEPHYR)
|
||||
zephyr_library_named(metal)
|
||||
add_dependencies(metal offsets_h)
|
||||
zephyr_library_sources(${_sources})
|
||||
zephyr_include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
else (WITH_ZEPHYR)
|
||||
# Build a shared library if so configured.
|
||||
if (WITH_SHARED_LIB)
|
||||
set (_lib ${PROJECT_NAME}-shared)
|
||||
add_library (${_lib} SHARED ${_sources})
|
||||
target_link_libraries (${_lib} ${_deps})
|
||||
install (TARGETS ${_lib} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if (PROJECT_EC_FLAGS)
|
||||
string(REPLACE " " ";" _ec_flgs ${PROJECT_EC_FLAGS})
|
||||
target_compile_options (${_lib} PUBLIC ${_ec_flgs})
|
||||
endif (PROJECT_EC_FLAGS)
|
||||
set_target_properties (${_lib} PROPERTIES
|
||||
OUTPUT_NAME "${PROJECT_NAME}"
|
||||
VERSION "${PROJECT_VER}"
|
||||
SOVERSION "${PROJECT_VER_MAJOR}"
|
||||
)
|
||||
endif (WITH_SHARED_LIB)
|
||||
|
||||
# Build a static library if so configured.
|
||||
if (WITH_STATIC_LIB)
|
||||
set (_lib ${PROJECT_NAME}-static)
|
||||
add_library (${_lib} STATIC ${_sources})
|
||||
install (TARGETS ${_lib} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if (PROJECT_EC_FLAGS)
|
||||
string(REPLACE " " ";" _ec_flgs ${PROJECT_EC_FLAGS})
|
||||
target_compile_options (${_lib} PUBLIC ${_ec_flgs})
|
||||
endif (PROJECT_EC_FLAGS)
|
||||
set_target_properties (${_lib} PROPERTIES
|
||||
OUTPUT_NAME "${PROJECT_NAME}"
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
endif (WITH_ZEPHYR)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file alloc.h
|
||||
* @brief Memory allocation handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ALLOC__H__
|
||||
#define __METAL_ALLOC__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup Memory Allocation Interfaces
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief allocate requested memory size
|
||||
* return a pointer to the allocated memory
|
||||
*
|
||||
* @param[in] size size in byte of requested memory
|
||||
* @return memory pointer, or 0 if it failed to allocate
|
||||
*/
|
||||
static inline void *metal_allocate_memory(unsigned int size);
|
||||
|
||||
/**
|
||||
* @brief free the memory previously allocated
|
||||
*
|
||||
* @param[in] ptr pointer to memory
|
||||
*/
|
||||
static inline void metal_free_memory(void *ptr);
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/alloc.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ALLOC__H__ */
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file assert.h
|
||||
* @brief Assertion support.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ASSERT__H__
|
||||
#define __METAL_ASSERT__H__
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/assert.h>
|
||||
|
||||
/**
|
||||
* @brief Assertion macro.
|
||||
* @param cond Condition to test.
|
||||
*/
|
||||
#define metal_assert(cond) metal_sys_assert(cond)
|
||||
|
||||
#endif /* __METAL_ASSERT_H__ */
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file atomic.h
|
||||
* @brief Atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ATOMIC__H__
|
||||
#define __METAL_ATOMIC__H__
|
||||
|
||||
#include <metal/config.h>
|
||||
|
||||
#if defined(HAVE_STDATOMIC_H) && !defined(__STDC_NO_ATOMICS__) && \
|
||||
!defined(__cplusplus)
|
||||
# include <stdint.h>
|
||||
# include <stdatomic.h>
|
||||
#elif defined(__cplusplus)
|
||||
# include <atomic>
|
||||
#elif defined(__GNUC__)
|
||||
# include <metal/compiler/gcc/atomic.h>
|
||||
#else
|
||||
# include <metal/processor/@PROJECT_PROCESSOR@/atomic.h>
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_ATOMIC__H__ */
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cache.h
|
||||
* @brief CACHE operation primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CACHE__H__
|
||||
#define __METAL_CACHE__H__
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/cache.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** \defgroup cache CACHE Interfaces
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief flush specified data cache
|
||||
*
|
||||
* @param[in] addr start memory logical address
|
||||
* @param[in] len length of memory
|
||||
* If addr is NULL, and len is 0,
|
||||
* It will flush the whole data cache.
|
||||
*/
|
||||
static inline void metal_cache_flush(void *addr, unsigned int len)
|
||||
{
|
||||
__metal_cache_flush(addr, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief invalidate specified data cache
|
||||
*
|
||||
* @param[in] addr start memory logical address
|
||||
* @param[in] len length of memory
|
||||
* If addr is NULL, and len is 0,
|
||||
* It will invalidate the whole data cache.
|
||||
*/
|
||||
static inline void metal_cache_invalidate(void *addr, unsigned int len)
|
||||
{
|
||||
__metal_cache_invalidate(addr, len);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CACHE__H__ */
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file compiler.h
|
||||
* @brief Compiler specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_COMPILER__H__
|
||||
#define __METAL_COMPILER__H__
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# include <metal/compiler/gcc/compiler.h>
|
||||
#elif defined(__ICCARM__)
|
||||
# include <metal/compiler/iar/compiler.h>
|
||||
#else
|
||||
# error "Missing compiler support"
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_COMPILER__H__ */
|
|
@ -1,4 +0,0 @@
|
|||
add_subdirectory (gcc)
|
||||
add_subdirectory (iar)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,4 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS compiler.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/atomic.h
|
||||
* @brief GCC specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_GCC_ATOMIC__H__
|
||||
#define __METAL_GCC_ATOMIC__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int atomic_flag;
|
||||
typedef char atomic_char;
|
||||
typedef unsigned char atomic_uchar;
|
||||
typedef short atomic_short;
|
||||
typedef unsigned short atomic_ushort;
|
||||
typedef int atomic_int;
|
||||
typedef unsigned int atomic_uint;
|
||||
typedef long atomic_long;
|
||||
typedef unsigned long atomic_ulong;
|
||||
typedef long long atomic_llong;
|
||||
typedef unsigned long long atomic_ullong;
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
#define ATOMIC_VAR_INIT(VAL) (VAL)
|
||||
|
||||
typedef enum {
|
||||
memory_order_relaxed,
|
||||
memory_order_consume,
|
||||
memory_order_acquire,
|
||||
memory_order_release,
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst,
|
||||
} memory_order;
|
||||
|
||||
#define atomic_flag_test_and_set(FLAG) \
|
||||
__sync_lock_test_and_set((FLAG), 1)
|
||||
#define atomic_flag_test_and_set_explicit(FLAG, MO) \
|
||||
atomic_flag_test_and_set(FLAG)
|
||||
#define atomic_flag_clear(FLAG) \
|
||||
__sync_lock_release((FLAG))
|
||||
#define atomic_flag_clear_explicit(FLAG, MO) \
|
||||
atomic_flag_clear(FLAG)
|
||||
#define atomic_init(OBJ, VAL) \
|
||||
do { *(OBJ) = (VAL); } while (0)
|
||||
#define atomic_is_lock_free(OBJ) \
|
||||
(sizeof(*(OBJ)) <= sizeof(long))
|
||||
#define atomic_store(OBJ, VAL) \
|
||||
do { *(OBJ) = (VAL); __sync_synchronize(); } while (0)
|
||||
#define atomic_store_explicit(OBJ, VAL, MO) \
|
||||
atomic_store((OBJ), (VAL))
|
||||
#define atomic_load(OBJ) \
|
||||
({ __sync_synchronize(); *(OBJ); })
|
||||
#define atomic_load_explicit(OBJ, MO) \
|
||||
atomic_load(OBJ)
|
||||
#define atomic_exchange(OBJ, DES) \
|
||||
({ \
|
||||
typeof(OBJ) obj = (OBJ); \
|
||||
typeof(*obj) des = (DES); \
|
||||
typeof(*obj) expval; \
|
||||
typeof(*obj) oldval = atomic_load(obj); \
|
||||
do { \
|
||||
expval = oldval; \
|
||||
oldval = __sync_val_compare_and_swap( \
|
||||
obj, expval, des); \
|
||||
} while (oldval != expval); \
|
||||
oldval; \
|
||||
})
|
||||
#define atomic_exchange_explicit(OBJ, DES, MO) \
|
||||
atomic_exchange((OBJ), (DES))
|
||||
#define atomic_compare_exchange_strong(OBJ, EXP, DES) \
|
||||
({ \
|
||||
typeof(OBJ) obj = (OBJ); \
|
||||
typeof(EXP) exp = (EXP); \
|
||||
typeof(*obj) expval = *exp; \
|
||||
typeof(*obj) oldval = __sync_val_compare_and_swap( \
|
||||
obj, expval, (DES)); \
|
||||
*exp = oldval; \
|
||||
oldval == expval; \
|
||||
})
|
||||
#define atomic_compare_exchange_strong_explicit(OBJ, EXP, DES, MO) \
|
||||
atomic_compare_exchange_strong((OBJ), (EXP), (DES))
|
||||
#define atomic_compare_exchange_weak(OBJ, EXP, DES) \
|
||||
atomic_compare_exchange_strong((OBJ), (EXP), (DES))
|
||||
#define atomic_compare_exchange_weak_explicit(OBJ, EXP, DES, MO) \
|
||||
atomic_compare_exchange_weak((OBJ), (EXP), (DES))
|
||||
#define atomic_fetch_add(OBJ, VAL) \
|
||||
__sync_fetch_and_add((OBJ), (VAL))
|
||||
#define atomic_fetch_add_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_add((OBJ), (VAL))
|
||||
#define atomic_fetch_sub(OBJ, VAL) \
|
||||
__sync_fetch_and_sub((OBJ), (VAL))
|
||||
#define atomic_fetch_sub_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_sub((OBJ), (VAL))
|
||||
#define atomic_fetch_or(OBJ, VAL) \
|
||||
__sync_fetch_and_or((OBJ), (VAL))
|
||||
#define atomic_fetch_or_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_or((OBJ), (VAL))
|
||||
#define atomic_fetch_xor(OBJ, VAL) \
|
||||
__sync_fetch_and_xor((OBJ), (VAL))
|
||||
#define atomic_fetch_xor_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_xor((OBJ), (VAL))
|
||||
#define atomic_fetch_and(OBJ, VAL) \
|
||||
__sync_fetch_and_and((OBJ), (VAL))
|
||||
#define atomic_fetch_and_explicit(OBJ, VAL, MO) \
|
||||
atomic_fetch_and((OBJ), (VAL))
|
||||
#define atomic_thread_fence(MO) \
|
||||
__sync_synchronize()
|
||||
#define atomic_signal_fence(MO) \
|
||||
__sync_synchronize()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GCC_ATOMIC__H__ */
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/compiler.h
|
||||
* @brief GCC specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_GCC_COMPILER__H__
|
||||
#define __METAL_GCC_COMPILER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
#define metal_align(n) __attribute__((aligned(n)))
|
||||
#define metal_weak __attribute__((weak))
|
||||
|
||||
#define METAL_PACKED_BEGIN
|
||||
#define METAL_PACKED_END __attribute__((__packed__))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_GCC_COMPILER__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS compiler.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ST Microelectronics. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file iar/compiler.h
|
||||
* @brief IAR specific primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IAR_COMPILER__H__
|
||||
#define __METAL_IAR_COMPILER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
#define metal_align(n) __attribute__((aligned(n)))
|
||||
#define metal_weak __attribute__((weak))
|
||||
|
||||
#define METAL_PACKED_BEGIN __packed
|
||||
#define METAL_PACKED_END
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IAR_COMPILER__H__ */
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file condition.h
|
||||
* @brief Condition variable for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONDITION__H__
|
||||
#define __METAL_CONDITION__H__
|
||||
|
||||
#include <metal/mutex.h>
|
||||
#include <metal/utilities.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup condition Condition Variable Interfaces
|
||||
* @{ */
|
||||
|
||||
/** Opaque libmetal condition variable data structure. */
|
||||
struct metal_condition;
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal condition variable.
|
||||
* @param[in] cv condition variable to initialize.
|
||||
*/
|
||||
static inline void metal_condition_init(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Notify one waiter.
|
||||
* Before calling this function, the caller
|
||||
* should have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @return zero on no errors, non-zero on errors
|
||||
* @see metal_condition_wait, metal_condition_broadcast
|
||||
*/
|
||||
static inline int metal_condition_signal(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Notify all waiters.
|
||||
* Before calling this function, the caller
|
||||
* should have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @return zero on no errors, non-zero on errors
|
||||
* @see metal_condition_wait, metal_condition_signal
|
||||
*/
|
||||
static inline int metal_condition_broadcast(struct metal_condition *cv);
|
||||
|
||||
/**
|
||||
* @brief Block until the condition variable is notified.
|
||||
* Before calling this function, the caller should
|
||||
* have acquired the mutex.
|
||||
* @param[in] cv condition variable
|
||||
* @param[in] m mutex
|
||||
* @return 0 on success, non-zero on failure.
|
||||
* @see metal_condition_signal
|
||||
*/
|
||||
int metal_condition_wait(struct metal_condition *cv, metal_mutex_t *m);
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/condition.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CONDITION__H__ */
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file config.h
|
||||
* @brief Generated configuration settings for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONFIG__H__
|
||||
#define __METAL_CONFIG__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Library major version number. */
|
||||
#define METAL_VER_MAJOR @PROJECT_VER_MAJOR@
|
||||
|
||||
/** Library minor version number. */
|
||||
#define METAL_VER_MINOR @PROJECT_VER_MINOR@
|
||||
|
||||
/** Library patch level. */
|
||||
#define METAL_VER_PATCH @PROJECT_VER_PATCH@
|
||||
|
||||
/** Library version string. */
|
||||
#define METAL_VER "@PROJECT_VER@"
|
||||
|
||||
/** System type (linux, generic, ...). */
|
||||
#define METAL_SYSTEM "@PROJECT_SYSTEM@"
|
||||
#define METAL_SYSTEM_@PROJECT_SYSTEM_UPPER@
|
||||
|
||||
/** Processor type (arm, x86_64, ...). */
|
||||
#define METAL_PROCESSOR "@PROJECT_PROCESSOR@"
|
||||
#define METAL_PROCESSOR_@PROJECT_PROCESSOR_UPPER@
|
||||
|
||||
/** Machine type (zynq, zynqmp, ...). */
|
||||
#define METAL_MACHINE "@PROJECT_MACHINE@"
|
||||
#define METAL_MACHINE_@PROJECT_MACHINE_UPPER@
|
||||
|
||||
#cmakedefine HAVE_STDATOMIC_H
|
||||
#cmakedefine HAVE_FUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CONFIG__H__ */
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CPU__H__
|
||||
#define __METAL_CPU__H__
|
||||
|
||||
# include <metal/processor/@PROJECT_PROCESSOR@/cpu.h>
|
||||
|
||||
#endif /* __METAL_CPU__H__ */
|
|
@ -1,167 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <metal/assert.h>
|
||||
#include <metal/device.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/log.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/utilities.h>
|
||||
#include <metal/dma.h>
|
||||
#include <metal/cache.h>
|
||||
|
||||
int metal_bus_register(struct metal_bus *bus)
|
||||
{
|
||||
if (!bus || !bus->name || !strlen(bus->name))
|
||||
return -EINVAL;
|
||||
if (metal_bus_find(bus->name, NULL) == 0)
|
||||
return -EEXIST;
|
||||
metal_list_init(&bus->devices);
|
||||
metal_list_add_tail(&_metal.common.bus_list, &bus->node);
|
||||
metal_log(METAL_LOG_DEBUG, "registered %s bus\n", bus->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metal_bus_unregister(struct metal_bus *bus)
|
||||
{
|
||||
metal_list_del(&bus->node);
|
||||
if (bus->ops.bus_close)
|
||||
bus->ops.bus_close(bus);
|
||||
metal_log(METAL_LOG_DEBUG, "unregistered %s bus\n", bus->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metal_bus_find(const char *name, struct metal_bus **result)
|
||||
{
|
||||
struct metal_list *node;
|
||||
struct metal_bus *bus;
|
||||
|
||||
metal_list_for_each(&_metal.common.bus_list, node) {
|
||||
bus = metal_container_of(node, struct metal_bus, node);
|
||||
if (strcmp(bus->name, name) != 0)
|
||||
continue;
|
||||
if (result)
|
||||
*result = bus;
|
||||
return 0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int metal_device_open(const char *bus_name, const char *dev_name,
|
||||
struct metal_device **device)
|
||||
{
|
||||
struct metal_bus *bus;
|
||||
int error;
|
||||
|
||||
if (!bus_name || !strlen(bus_name) ||
|
||||
!dev_name || !strlen(dev_name) ||
|
||||
!device)
|
||||
return -EINVAL;
|
||||
|
||||
error = metal_bus_find(bus_name, &bus);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!bus->ops.dev_open)
|
||||
return -ENODEV;
|
||||
|
||||
error = (*bus->ops.dev_open)(bus, dev_name, device);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void metal_device_close(struct metal_device *device)
|
||||
{
|
||||
metal_assert(device && device->bus);
|
||||
if (device->bus->ops.dev_close)
|
||||
device->bus->ops.dev_close(device->bus, device);
|
||||
}
|
||||
|
||||
int metal_register_generic_device(struct metal_device *device)
|
||||
{
|
||||
if (!device->name || !strlen(device->name) ||
|
||||
device->num_regions > METAL_MAX_DEVICE_REGIONS)
|
||||
return -EINVAL;
|
||||
|
||||
device->bus = &metal_generic_bus;
|
||||
metal_list_add_tail(&_metal.common.generic_device_list,
|
||||
&device->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
|
||||
struct metal_device **device)
|
||||
{
|
||||
struct metal_list *node;
|
||||
struct metal_device *dev;
|
||||
|
||||
(void)bus;
|
||||
|
||||
metal_list_for_each(&_metal.common.generic_device_list, node) {
|
||||
dev = metal_container_of(node, struct metal_device, node);
|
||||
if (strcmp(dev->name, dev_name) != 0)
|
||||
continue;
|
||||
*device = dev;
|
||||
return metal_generic_dev_sys_open(dev);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int metal_generic_dev_dma_map(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out)
|
||||
{
|
||||
(void)bus;
|
||||
(void)device;
|
||||
int i;
|
||||
|
||||
if (sg_out != sg_in)
|
||||
memcpy(sg_out, sg_in, nents_in*(sizeof(struct metal_sg)));
|
||||
for (i = 0; i < nents_in; i++) {
|
||||
if (dir == METAL_DMA_DEV_W) {
|
||||
metal_cache_flush(sg_out[i].virt, sg_out[i].len);
|
||||
}
|
||||
metal_cache_invalidate(sg_out[i].virt, sg_out[i].len);
|
||||
}
|
||||
|
||||
return nents_in;
|
||||
}
|
||||
|
||||
void metal_generic_dev_dma_unmap(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents)
|
||||
{
|
||||
(void)bus;
|
||||
(void)device;
|
||||
(void)dir;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nents; i++) {
|
||||
metal_cache_invalidate(sg[i].virt, sg[i].len);
|
||||
}
|
||||
}
|
||||
|
||||
struct metal_bus metal_weak metal_generic_bus = {
|
||||
.name = "generic",
|
||||
.ops = {
|
||||
.bus_close = NULL,
|
||||
.dev_open = metal_generic_dev_open,
|
||||
.dev_close = NULL,
|
||||
.dev_irq_ack = NULL,
|
||||
.dev_dma_map = metal_generic_dev_dma_map,
|
||||
.dev_dma_unmap = metal_generic_dev_dma_unmap,
|
||||
},
|
||||
};
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file device.h
|
||||
* @brief Bus abstraction for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_BUS__H__
|
||||
#define __METAL_BUS__H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <metal/io.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/dma.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup device Bus Abstraction
|
||||
* @{ */
|
||||
|
||||
#ifndef METAL_MAX_DEVICE_REGIONS
|
||||
#define METAL_MAX_DEVICE_REGIONS 32
|
||||
#endif
|
||||
|
||||
struct metal_bus;
|
||||
struct metal_device;
|
||||
|
||||
/** Bus operations. */
|
||||
struct metal_bus_ops {
|
||||
void (*bus_close)(struct metal_bus *bus);
|
||||
int (*dev_open)(struct metal_bus *bus,
|
||||
const char *dev_name,
|
||||
struct metal_device **device);
|
||||
void (*dev_close)(struct metal_bus *bus,
|
||||
struct metal_device *device);
|
||||
void (*dev_irq_ack)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
int irq);
|
||||
int (*dev_dma_map)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
void (*dev_dma_unmap)(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
};
|
||||
|
||||
/** Libmetal bus structure. */
|
||||
struct metal_bus {
|
||||
const char *name;
|
||||
struct metal_bus_ops ops;
|
||||
struct metal_list devices;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/** Libmetal generic bus. */
|
||||
extern struct metal_bus metal_generic_bus;
|
||||
|
||||
/** Libmetal device structure. */
|
||||
struct metal_device {
|
||||
const char *name; /**< Device name */
|
||||
struct metal_bus *bus; /**< Bus that contains device */
|
||||
unsigned num_regions; /**< Number of I/O regions in
|
||||
device */
|
||||
struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of
|
||||
I/O regions in device*/
|
||||
struct metal_list node; /**< Node on bus' list of devices */
|
||||
int irq_num; /**< Number of IRQs per device */
|
||||
void *irq_info; /**< IRQ ID */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register a libmetal bus.
|
||||
* @param[in] bus Pre-initialized bus structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_register(struct metal_bus *bus);
|
||||
|
||||
/**
|
||||
* @brief Unregister a libmetal bus.
|
||||
* @param[in] bus Pre-registered bus structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_unregister(struct metal_bus *bus);
|
||||
|
||||
/**
|
||||
* @brief Find a libmetal bus by name.
|
||||
* @param[in] name Bus name.
|
||||
* @param[out] bus Returned bus handle.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_bus_find(const char *name, struct metal_bus **bus);
|
||||
|
||||
/**
|
||||
* @brief Statically register a generic libmetal device.
|
||||
*
|
||||
* In non-Linux systems, devices are always required to be statically
|
||||
* registered at application initialization.
|
||||
* In Linux system, devices can be dynamically opened via sysfs or libfdt based
|
||||
* enumeration at runtime.
|
||||
* This interface is used for static registration of devices. Subsequent calls
|
||||
* to metal_device_open() look up in this list of pre-registered devices on the
|
||||
* "generic" bus.
|
||||
* "generic" bus is used on non-Linux system to group the memory mapped devices.
|
||||
*
|
||||
* @param[in] device Generic device.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_register_generic_device(struct metal_device *device);
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal device by name.
|
||||
* @param[in] bus_name Bus name.
|
||||
* @param[in] dev_name Device name.
|
||||
* @param[out] device Returned device handle.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_device_open(const char *bus_name, const char *dev_name,
|
||||
struct metal_device **device);
|
||||
|
||||
/**
|
||||
* @brief Close a libmetal device.
|
||||
* @param[in] device Device handle.
|
||||
*/
|
||||
extern void metal_device_close(struct metal_device *device);
|
||||
|
||||
/**
|
||||
* @brief Get an I/O region accessor for a device region.
|
||||
*
|
||||
* @param[in] device Device handle.
|
||||
* @param[in] index Region index.
|
||||
* @return I/O accessor handle, or NULL on failure.
|
||||
*/
|
||||
static inline struct metal_io_region *
|
||||
metal_device_io_region(struct metal_device *device, unsigned index)
|
||||
{
|
||||
return (index < device->num_regions
|
||||
? &device->regions[index]
|
||||
: NULL);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
extern int metal_generic_dev_sys_open(struct metal_device *dev);
|
||||
extern int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
|
||||
struct metal_device **device);
|
||||
extern int metal_generic_dev_dma_map(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
extern void metal_generic_dev_dma_unmap(struct metal_bus *bus,
|
||||
struct metal_device *device,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
#endif /* METAL_INTERNAL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_BUS__H__ */
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <metal/device.h>
|
||||
#include <metal/log.h>
|
||||
#include <metal/dma.h>
|
||||
#include <metal/atomic.h>
|
||||
|
||||
int metal_dma_map(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out)
|
||||
{
|
||||
int nents_out;
|
||||
|
||||
if (!dev || !sg_in || !sg_out)
|
||||
return -EINVAL;
|
||||
if (!dev->bus->ops.dev_dma_map)
|
||||
return -ENODEV;
|
||||
|
||||
/* memory barrier */
|
||||
if (dir == METAL_DMA_DEV_R)
|
||||
/* If it is device read, apply memory write fence. */
|
||||
atomic_thread_fence(memory_order_release);
|
||||
else
|
||||
/* If it is device write or device r/w,
|
||||
apply memory r/w fence. */
|
||||
atomic_thread_fence(memory_order_acq_rel);
|
||||
nents_out = dev->bus->ops.dev_dma_map(dev->bus,
|
||||
dev, dir, sg_in, nents_in, sg_out);
|
||||
return nents_out;
|
||||
}
|
||||
|
||||
void metal_dma_unmap(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents)
|
||||
{
|
||||
/* memory barrier */
|
||||
if (dir == METAL_DMA_DEV_R)
|
||||
/* If it is device read, apply memory write fence. */
|
||||
atomic_thread_fence(memory_order_release);
|
||||
else
|
||||
/* If it is device write or device r/w,
|
||||
apply memory r/w fence. */
|
||||
atomic_thread_fence(memory_order_acq_rel);
|
||||
|
||||
if (!dev || !dev->bus->ops.dev_dma_unmap || !sg)
|
||||
return;
|
||||
dev->bus->ops.dev_dma_unmap(dev->bus,
|
||||
dev, dir, sg, nents);
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file dma.h
|
||||
* @brief DMA primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_DMA__H__
|
||||
#define __METAL_DMA__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup dma DMA Interfaces
|
||||
* @{ */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
#define METAL_DMA_DEV_R 1 /**< DMA direction, device read */
|
||||
#define METAL_DMA_DEV_W 2 /**< DMA direction, device write */
|
||||
#define METAL_DMA_DEV_WR 3 /**< DMA direction, device read/write */
|
||||
|
||||
/**
|
||||
* @brief scatter/gather list element structure
|
||||
*/
|
||||
struct metal_sg {
|
||||
void *virt; /**< CPU virtual address */
|
||||
struct metal_io_region *io; /**< IO region */
|
||||
int len; /**< length */
|
||||
};
|
||||
|
||||
struct metal_device;
|
||||
|
||||
/**
|
||||
* @brief Map memory for DMA transaction.
|
||||
* After the memory is DMA mapped, the memory should be
|
||||
* accessed by the DMA device but not the CPU.
|
||||
*
|
||||
* @param[in] dev DMA device
|
||||
* @param[in] dir DMA direction
|
||||
* @param[in] sg_in sg list of memory to map
|
||||
* @param[in] nents_in number of sg list entries of memory to map
|
||||
* @param[out] sg_out sg list of mapped memory
|
||||
* @return number of mapped sg entries, -error on failure.
|
||||
*/
|
||||
int metal_dma_map(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg_in,
|
||||
int nents_in,
|
||||
struct metal_sg *sg_out);
|
||||
|
||||
/**
|
||||
* @brief Unmap DMA memory
|
||||
* After the memory is DMA unmapped, the memory should
|
||||
* be accessed by the CPU but not the DMA device.
|
||||
*
|
||||
* @param[in] dev DMA device
|
||||
* @param[in] dir DMA direction
|
||||
* @param[in] sg sg list of mapped DMA memory
|
||||
* @param[in] nents number of sg list entries of DMA memory
|
||||
*/
|
||||
void metal_dma_unmap(struct metal_device *dev,
|
||||
uint32_t dir,
|
||||
struct metal_sg *sg,
|
||||
int nents);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_DMA__H__ */
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
int metal_init(const struct metal_init_params *params)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
memset(&_metal, 0, sizeof(_metal));
|
||||
|
||||
_metal.common.log_handler = params->log_handler;
|
||||
_metal.common.log_level = params->log_level;
|
||||
|
||||
metal_list_init(&_metal.common.bus_list);
|
||||
metal_list_init(&_metal.common.generic_shmem_list);
|
||||
metal_list_init(&_metal.common.generic_device_list);
|
||||
|
||||
error = metal_sys_init(params);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void metal_finish(void)
|
||||
{
|
||||
metal_sys_finish();
|
||||
memset(&_metal, 0, sizeof(_metal));
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <metal/io.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
void metal_io_init(struct metal_io_region *io, void *virt,
|
||||
const metal_phys_addr_t *physmap, size_t size,
|
||||
unsigned page_shift, unsigned int mem_flags,
|
||||
const struct metal_io_ops *ops)
|
||||
{
|
||||
const struct metal_io_ops nops = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
io->virt = virt;
|
||||
io->physmap = physmap;
|
||||
io->size = size;
|
||||
io->page_shift = page_shift;
|
||||
if (page_shift >= sizeof(io->page_mask) * CHAR_BIT)
|
||||
/* avoid overflow */
|
||||
io->page_mask = -1UL;
|
||||
else
|
||||
io->page_mask = (1UL << page_shift) - 1UL;
|
||||
io->mem_flags = mem_flags;
|
||||
io->ops = ops ? *ops : nops;
|
||||
metal_sys_io_mem_map(io);
|
||||
}
|
||||
|
||||
int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
|
||||
void *restrict dst, int len)
|
||||
{
|
||||
unsigned char *ptr = metal_io_virt(io, offset);
|
||||
unsigned char *dest = dst;
|
||||
int retlen;
|
||||
|
||||
if (offset >= io->size)
|
||||
return -ERANGE;
|
||||
if ((offset + len) > io->size)
|
||||
len = io->size - offset;
|
||||
retlen = len;
|
||||
if (io->ops.block_read) {
|
||||
retlen = (*io->ops.block_read)(
|
||||
io, offset, dst, memory_order_seq_cst, len);
|
||||
} else {
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
while ( len && (
|
||||
((uintptr_t)dest % sizeof(int)) ||
|
||||
((uintptr_t)ptr % sizeof(int)))) {
|
||||
*(unsigned char *)dest =
|
||||
*(const unsigned char *)ptr;
|
||||
dest++;
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
for (; len >= (int)sizeof(int); dest += sizeof(int),
|
||||
ptr += sizeof(int),
|
||||
len -= sizeof(int))
|
||||
*(unsigned int *)dest = *(const unsigned int *)ptr;
|
||||
for (; len != 0; dest++, ptr++, len--)
|
||||
*(unsigned char *)dest =
|
||||
*(const unsigned char *)ptr;
|
||||
}
|
||||
return retlen;
|
||||
}
|
||||
|
||||
int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
|
||||
const void *restrict src, int len)
|
||||
{
|
||||
unsigned char *ptr = metal_io_virt(io, offset);
|
||||
const unsigned char *source = src;
|
||||
int retlen;
|
||||
|
||||
if (offset >= io->size)
|
||||
return -ERANGE;
|
||||
if ((offset + len) > io->size)
|
||||
len = io->size - offset;
|
||||
retlen = len;
|
||||
if (io->ops.block_write) {
|
||||
retlen = (*io->ops.block_write)(
|
||||
io, offset, src, memory_order_seq_cst, len);
|
||||
} else {
|
||||
while ( len && (
|
||||
((uintptr_t)ptr % sizeof(int)) ||
|
||||
((uintptr_t)source % sizeof(int)))) {
|
||||
*(unsigned char *)ptr =
|
||||
*(const unsigned char *)source;
|
||||
ptr++;
|
||||
source++;
|
||||
len--;
|
||||
}
|
||||
for (; len >= (int)sizeof(int); ptr += sizeof(int),
|
||||
source += sizeof(int),
|
||||
len -= sizeof(int))
|
||||
*(unsigned int *)ptr = *(const unsigned int *)source;
|
||||
for (; len != 0; ptr++, source++, len--)
|
||||
*(unsigned char *)ptr =
|
||||
*(const unsigned char *)source;
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
}
|
||||
return retlen;
|
||||
}
|
||||
|
||||
int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
|
||||
unsigned char value, int len)
|
||||
{
|
||||
unsigned char *ptr = metal_io_virt(io, offset);
|
||||
int retlen = len;
|
||||
|
||||
if (offset >= io->size)
|
||||
return -ERANGE;
|
||||
if ((offset + len) > io->size)
|
||||
len = io->size - offset;
|
||||
retlen = len;
|
||||
if (io->ops.block_set) {
|
||||
(*io->ops.block_set)(
|
||||
io, offset, value, memory_order_seq_cst, len);
|
||||
} else {
|
||||
unsigned int cint = value;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < sizeof(int); i++)
|
||||
cint |= ((unsigned int)value << (CHAR_BIT * i));
|
||||
|
||||
for (; len && ((uintptr_t)ptr % sizeof(int)); ptr++, len--)
|
||||
*(unsigned char *)ptr = (unsigned char) value;
|
||||
for (; len >= (int)sizeof(int); ptr += sizeof(int),
|
||||
len -= sizeof(int))
|
||||
*(unsigned int *)ptr = cint;
|
||||
for (; len != 0; ptr++, len--)
|
||||
*(unsigned char *)ptr = (unsigned char) value;
|
||||
atomic_thread_fence(memory_order_seq_cst);
|
||||
}
|
||||
return retlen;
|
||||
}
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2017, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file io.h
|
||||
* @brief I/O access primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IO__H__
|
||||
#define __METAL_IO__H__
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <metal/assert.h>
|
||||
#include <metal/compiler.h>
|
||||
#include <metal/atomic.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/cpu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup io IO Interfaces
|
||||
* @{ */
|
||||
|
||||
#ifdef __MICROBLAZE__
|
||||
#define NO_ATOMIC_64_SUPPORT
|
||||
#endif
|
||||
|
||||
struct metal_io_region;
|
||||
|
||||
/** Generic I/O operations. */
|
||||
struct metal_io_ops {
|
||||
uint64_t (*read)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
memory_order order,
|
||||
int width);
|
||||
void (*write)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
uint64_t value,
|
||||
memory_order order,
|
||||
int width);
|
||||
int (*block_read)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
void *restrict dst,
|
||||
memory_order order,
|
||||
int len);
|
||||
int (*block_write)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
const void *restrict src,
|
||||
memory_order order,
|
||||
int len);
|
||||
void (*block_set)(struct metal_io_region *io,
|
||||
unsigned long offset,
|
||||
unsigned char value,
|
||||
memory_order order,
|
||||
int len);
|
||||
void (*close)(struct metal_io_region *io);
|
||||
metal_phys_addr_t
|
||||
(*offset_to_phys)(struct metal_io_region *io,
|
||||
unsigned long offset);
|
||||
unsigned long (*phys_to_offset)(struct metal_io_region *io,
|
||||
metal_phys_addr_t phys);
|
||||
};
|
||||
|
||||
/** Libmetal I/O region structure. */
|
||||
struct metal_io_region {
|
||||
void *virt; /**< base virtual address */
|
||||
const metal_phys_addr_t *physmap; /**< table of base physical address
|
||||
of each of the pages in the I/O
|
||||
region */
|
||||
size_t size; /**< size of the I/O region */
|
||||
unsigned long page_shift; /**< page shift of I/O region */
|
||||
metal_phys_addr_t page_mask; /**< page mask of I/O region */
|
||||
unsigned int mem_flags; /**< memory attribute of the
|
||||
I/O region */
|
||||
struct metal_io_ops ops; /**< I/O region operations */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal I/O region.
|
||||
*
|
||||
* @param[in, out] io I/O region handle.
|
||||
* @param[in] virt Virtual address of region.
|
||||
* @param[in] physmap Array of physical addresses per page.
|
||||
* @param[in] size Size of region.
|
||||
* @param[in] page_shift Log2 of page size (-1 for single page).
|
||||
* @param[in] mem_flags Memory flags
|
||||
* @param[in] ops ops
|
||||
*/
|
||||
void
|
||||
metal_io_init(struct metal_io_region *io, void *virt,
|
||||
const metal_phys_addr_t *physmap, size_t size,
|
||||
unsigned page_shift, unsigned int mem_flags,
|
||||
const struct metal_io_ops *ops);
|
||||
|
||||
/**
|
||||
* @brief Close a libmetal shared memory segment.
|
||||
* @param[in] io I/O region handle.
|
||||
*/
|
||||
static inline void metal_io_finish(struct metal_io_region *io)
|
||||
{
|
||||
if (io->ops.close)
|
||||
(*io->ops.close)(io);
|
||||
memset(io, 0, sizeof(*io));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get size of I/O region.
|
||||
*
|
||||
* @param[in] io I/O region handle.
|
||||
* @return Size of I/O region.
|
||||
*/
|
||||
static inline size_t metal_io_region_size(struct metal_io_region *io)
|
||||
{
|
||||
return io->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get virtual address for a given offset into the I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into shared memory segment.
|
||||
* @return NULL if offset is out of range, or pointer to offset.
|
||||
*/
|
||||
static inline void *
|
||||
metal_io_virt(struct metal_io_region *io, unsigned long offset)
|
||||
{
|
||||
return (io->virt != METAL_BAD_VA && offset < io->size
|
||||
? (uint8_t *)io->virt + offset
|
||||
: NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a virtual address to offset within I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] virt Virtual address within segment.
|
||||
* @return METAL_BAD_OFFSET if out of range, or offset.
|
||||
*/
|
||||
static inline unsigned long
|
||||
metal_io_virt_to_offset(struct metal_io_region *io, void *virt)
|
||||
{
|
||||
size_t offset = (uint8_t *)virt - (uint8_t *)io->virt;
|
||||
return (offset < io->size ? offset : METAL_BAD_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get physical address for a given offset into the I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into shared memory segment.
|
||||
* @return METAL_BAD_PHYS if offset is out of range, or physical address
|
||||
* of offset.
|
||||
*/
|
||||
static inline metal_phys_addr_t
|
||||
metal_io_phys(struct metal_io_region *io, unsigned long offset)
|
||||
{
|
||||
if (!io->ops.offset_to_phys) {
|
||||
unsigned long page = (io->page_shift >=
|
||||
sizeof(offset) * CHAR_BIT ?
|
||||
0 : offset >> io->page_shift);
|
||||
return (io->physmap != NULL && offset < io->size
|
||||
? io->physmap[page] + (offset & io->page_mask)
|
||||
: METAL_BAD_PHYS);
|
||||
}
|
||||
|
||||
return io->ops.offset_to_phys(io, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a physical address to offset within I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] phys Physical address within segment.
|
||||
* @return METAL_BAD_OFFSET if out of range, or offset.
|
||||
*/
|
||||
static inline unsigned long
|
||||
metal_io_phys_to_offset(struct metal_io_region *io, metal_phys_addr_t phys)
|
||||
{
|
||||
if (!io->ops.phys_to_offset) {
|
||||
unsigned long offset =
|
||||
(io->page_mask == (metal_phys_addr_t)(-1) ?
|
||||
phys - io->physmap[0] : phys & io->page_mask);
|
||||
do {
|
||||
if (metal_io_phys(io, offset) == phys)
|
||||
return offset;
|
||||
offset += io->page_mask + 1;
|
||||
} while (offset < io->size);
|
||||
return METAL_BAD_OFFSET;
|
||||
}
|
||||
|
||||
return (*io->ops.phys_to_offset)(io, phys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a physical address to virtual address.
|
||||
* @param[in] io Shared memory segment handle.
|
||||
* @param[in] phys Physical address within segment.
|
||||
* @return NULL if out of range, or corresponding virtual address.
|
||||
*/
|
||||
static inline void *
|
||||
metal_io_phys_to_virt(struct metal_io_region *io, metal_phys_addr_t phys)
|
||||
{
|
||||
return metal_io_virt(io, metal_io_phys_to_offset(io, phys));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a virtual address to physical address.
|
||||
* @param[in] io Shared memory segment handle.
|
||||
* @param[in] virt Virtual address within segment.
|
||||
* @return METAL_BAD_PHYS if out of range, or corresponding
|
||||
* physical address.
|
||||
*/
|
||||
static inline metal_phys_addr_t
|
||||
metal_io_virt_to_phys(struct metal_io_region *io, void *virt)
|
||||
{
|
||||
return metal_io_phys(io, metal_io_virt_to_offset(io, virt));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] order Memory ordering.
|
||||
* @param[in] width Width in bytes of datatype to read. This must be 1, 2,
|
||||
* 4, or 8, and a compile time constant for this function
|
||||
* to inline cleanly.
|
||||
* @return Value.
|
||||
*/
|
||||
static inline uint64_t
|
||||
metal_io_read(struct metal_io_region *io, unsigned long offset,
|
||||
memory_order order, int width)
|
||||
{
|
||||
void *ptr = metal_io_virt(io, offset);
|
||||
|
||||
if (io->ops.read)
|
||||
return (*io->ops.read)(io, offset, order, width);
|
||||
else if (ptr && sizeof(atomic_uchar) == width)
|
||||
return atomic_load_explicit((atomic_uchar *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_ushort) == width)
|
||||
return atomic_load_explicit((atomic_ushort *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_uint) == width)
|
||||
return atomic_load_explicit((atomic_uint *)ptr, order);
|
||||
else if (ptr && sizeof(atomic_ulong) == width)
|
||||
return atomic_load_explicit((atomic_ulong *)ptr, order);
|
||||
#ifndef NO_ATOMIC_64_SUPPORT
|
||||
else if (ptr && sizeof(atomic_ullong) == width)
|
||||
return atomic_load_explicit((atomic_ullong *)ptr, order);
|
||||
#endif
|
||||
metal_assert(0);
|
||||
return 0; /* quiet compiler */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a value into an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] value Value to write.
|
||||
* @param[in] order Memory ordering.
|
||||
* @param[in] width Width in bytes of datatype to read. This must be 1, 2,
|
||||
* 4, or 8, and a compile time constant for this function
|
||||
* to inline cleanly.
|
||||
*/
|
||||
static inline void
|
||||
metal_io_write(struct metal_io_region *io, unsigned long offset,
|
||||
uint64_t value, memory_order order, int width)
|
||||
{
|
||||
void *ptr = metal_io_virt(io, offset);
|
||||
if (io->ops.write)
|
||||
(*io->ops.write)(io, offset, value, order, width);
|
||||
else if (ptr && sizeof(atomic_uchar) == width)
|
||||
atomic_store_explicit((atomic_uchar *)ptr, value, order);
|
||||
else if (ptr && sizeof(atomic_ushort) == width)
|
||||
atomic_store_explicit((atomic_ushort *)ptr, value, order);
|
||||
else if (ptr && sizeof(atomic_uint) == width)
|
||||
atomic_store_explicit((atomic_uint *)ptr, value, order);
|
||||
else if (ptr && sizeof(atomic_ulong) == width)
|
||||
atomic_store_explicit((atomic_ulong *)ptr, value, order);
|
||||
#ifndef NO_ATOMIC_64_SUPPORT
|
||||
else if (ptr && sizeof(atomic_ullong) == width)
|
||||
atomic_store_explicit((atomic_ullong *)ptr, value, order);
|
||||
#endif
|
||||
else
|
||||
metal_assert (0);
|
||||
}
|
||||
|
||||
#define metal_io_read8_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 1)
|
||||
#define metal_io_read8(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 1)
|
||||
#define metal_io_write8_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 1)
|
||||
#define metal_io_write8(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 1)
|
||||
|
||||
#define metal_io_read16_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 2)
|
||||
#define metal_io_read16(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 2)
|
||||
#define metal_io_write16_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 2)
|
||||
#define metal_io_write16(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 2)
|
||||
|
||||
#define metal_io_read32_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 4)
|
||||
#define metal_io_read32(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 4)
|
||||
#define metal_io_write32_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 4)
|
||||
#define metal_io_write32(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 4)
|
||||
|
||||
#define metal_io_read64_explicit(_io, _ofs, _order) \
|
||||
metal_io_read((_io), (_ofs), (_order), 8)
|
||||
#define metal_io_read64(_io, _ofs) \
|
||||
metal_io_read((_io), (_ofs), memory_order_seq_cst, 8)
|
||||
#define metal_io_write64_explicit(_io, _ofs, _val, _order) \
|
||||
metal_io_write((_io), (_ofs), (_val), (_order), 8)
|
||||
#define metal_io_write64(_io, _ofs, _val) \
|
||||
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8)
|
||||
|
||||
/**
|
||||
* @brief Read a block from an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] dst destination to store the read data.
|
||||
* @param[in] len length in bytes to read.
|
||||
* @return On success, number of bytes read. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
|
||||
void *restrict dst, int len);
|
||||
|
||||
/**
|
||||
* @brief Write a block into an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] src source to write.
|
||||
* @param[in] len length in bytes to write.
|
||||
* @return On success, number of bytes written. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
|
||||
const void *restrict src, int len);
|
||||
|
||||
/**
|
||||
* @brief fill a block of an I/O region.
|
||||
* @param[in] io I/O region handle.
|
||||
* @param[in] offset Offset into I/O region.
|
||||
* @param[in] value value to fill into the block
|
||||
* @param[in] len length in bytes to fill.
|
||||
* @return On success, number of bytes filled. On failure, negative value
|
||||
*/
|
||||
int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
|
||||
unsigned char value, int len);
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/io.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IO__H__ */
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <metal/irq.h>
|
||||
#include <metal/irq_controller.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/utilities.h>
|
||||
|
||||
/** List of registered IRQ controller */
|
||||
static METAL_DECLARE_LIST(irq_cntrs);
|
||||
|
||||
static int metal_irq_allocate(int irq_base, int irq_num)
|
||||
{
|
||||
struct metal_list *node;
|
||||
struct metal_irq_controller *cntr;
|
||||
int irq_tocheck = irq_base, irq_end_tocheck;
|
||||
|
||||
if (irq_num == 0) {
|
||||
return METAL_IRQ_ANY;
|
||||
}
|
||||
if (irq_tocheck == METAL_IRQ_ANY) {
|
||||
irq_tocheck = 0;
|
||||
}
|
||||
irq_end_tocheck = irq_tocheck + irq_num;
|
||||
|
||||
metal_list_for_each(&irq_cntrs, node) {
|
||||
int cntr_irq_base, cntr_irq_end;
|
||||
|
||||
cntr = metal_container_of(node,
|
||||
struct metal_irq_controller, node);
|
||||
cntr_irq_base = cntr->irq_base;
|
||||
cntr_irq_end = cntr_irq_base + cntr->irq_num;
|
||||
if (irq_tocheck < cntr_irq_end &&
|
||||
irq_end_tocheck > cntr_irq_base) {
|
||||
if (irq_base != METAL_IRQ_ANY) {
|
||||
/* IRQ has been allocated */
|
||||
return METAL_IRQ_ANY;
|
||||
}
|
||||
irq_tocheck = cntr_irq_end;
|
||||
irq_end_tocheck = irq_tocheck + irq_num;
|
||||
}
|
||||
}
|
||||
return irq_tocheck;
|
||||
}
|
||||
|
||||
int metal_irq_register_controller(struct metal_irq_controller *cntr)
|
||||
{
|
||||
int irq_base;
|
||||
struct metal_list *node;
|
||||
|
||||
if (cntr == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
metal_list_for_each(&irq_cntrs, node) {
|
||||
if (node == &cntr->node) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate IRQ numbers which are not yet used by any IRQ
|
||||
* controllers.*/
|
||||
irq_base = metal_irq_allocate(cntr->irq_base , cntr->irq_num);
|
||||
if (irq_base == METAL_IRQ_ANY) {
|
||||
return -EINVAL;
|
||||
}
|
||||
cntr->irq_base = irq_base;
|
||||
|
||||
metal_list_add_tail(&irq_cntrs, &cntr->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct metal_irq_controller *metal_irq_get_controller(int irq)
|
||||
{
|
||||
struct metal_list *node;
|
||||
struct metal_irq_controller *cntr;
|
||||
|
||||
metal_list_for_each(&irq_cntrs, node) {
|
||||
int irq_base, irq_end;
|
||||
|
||||
cntr = (struct metal_irq_controller *)
|
||||
metal_container_of(node, struct metal_irq_controller,
|
||||
node);
|
||||
irq_base = cntr->irq_base;
|
||||
irq_end = irq_base + cntr->irq_num;
|
||||
if (irq >= irq_base && irq < irq_end) {
|
||||
return cntr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _metal_irq_set_enable(int irq, unsigned int state)
|
||||
{
|
||||
struct metal_irq_controller *cntr;
|
||||
|
||||
cntr = metal_irq_get_controller(irq);
|
||||
if (cntr == NULL) {
|
||||
return;
|
||||
}
|
||||
cntr->irq_set_enable(cntr, irq, state);
|
||||
}
|
||||
|
||||
int metal_irq_register(int irq,
|
||||
metal_irq_handler irq_handler,
|
||||
void *arg)
|
||||
{
|
||||
struct metal_irq_controller *cntr;
|
||||
struct metal_irq *irq_data;
|
||||
|
||||
cntr = metal_irq_get_controller(irq);
|
||||
if (cntr == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cntr->irq_register != NULL) {
|
||||
return cntr->irq_register(cntr, irq, irq_handler, arg);
|
||||
}
|
||||
if (cntr->irqs == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
irq_data = &cntr->irqs[irq - cntr->irq_base];
|
||||
irq_data->hd = irq_handler;
|
||||
irq_data->arg = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void metal_irq_enable(unsigned int vector)
|
||||
{
|
||||
_metal_irq_set_enable((int)vector, METAL_IRQ_ENABLE);
|
||||
}
|
||||
|
||||
void metal_irq_disable(unsigned int vector)
|
||||
{
|
||||
_metal_irq_set_enable((int)vector, METAL_IRQ_DISABLE);
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file irq.h
|
||||
* @brief Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IRQ__H__
|
||||
#define __METAL_IRQ__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup irq Interrupt Handling Interfaces
|
||||
* @{ */
|
||||
|
||||
#include <metal/list.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** IRQ handled status */
|
||||
#define METAL_IRQ_NOT_HANDLED 0
|
||||
#define METAL_IRQ_HANDLED 1
|
||||
|
||||
/**
|
||||
* @brief type of interrupt handler
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] arg argument to pass to the handler
|
||||
* @return irq handled status
|
||||
*/
|
||||
typedef int (*metal_irq_handler) (int irq, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Register interrupt handler for interrupt.
|
||||
* Only allow single interrupt handler for a interrupt.
|
||||
*
|
||||
* If irq_handler is NULL, it will unregister interrupt
|
||||
* handler from interrupt
|
||||
*
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] irq_handler interrupt handler
|
||||
* @param[in] arg arg is the argument pointing to the data which
|
||||
* will be passed to the interrupt handler.
|
||||
* @return 0 for success, non-zero on failure
|
||||
*/
|
||||
int metal_irq_register(int irq,
|
||||
metal_irq_handler irq_handler,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* @brief Unregister interrupt handler for interrupt.
|
||||
*
|
||||
* @param[in] irq interrupt id
|
||||
*/
|
||||
static inline
|
||||
void metal_irq_unregister(int irq)
|
||||
{
|
||||
metal_irq_register(irq, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief disable interrupts
|
||||
* @return interrupts state
|
||||
*/
|
||||
unsigned int metal_irq_save_disable(void);
|
||||
|
||||
/**
|
||||
* @brief restore interrupts to their previous state
|
||||
* @param[in] flags previous interrupts state
|
||||
*/
|
||||
void metal_irq_restore_enable(unsigned int flags);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_enable
|
||||
*
|
||||
* Enables the given interrupt
|
||||
*
|
||||
* @param vector - interrupt vector number
|
||||
*/
|
||||
void metal_irq_enable(unsigned int vector);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_disable
|
||||
*
|
||||
* Disables the given interrupt
|
||||
*
|
||||
* @param vector - interrupt vector number
|
||||
*/
|
||||
void metal_irq_disable(unsigned int vector);
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/irq.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IRQ__H__ */
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file irq.h
|
||||
* @brief Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_IRQ_CONTROLLER__H__
|
||||
#define __METAL_IRQ_CONTROLLER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup irq Interrupt Handling Interfaces
|
||||
* @{ */
|
||||
|
||||
#include <metal/irq.h>
|
||||
#include <metal/list.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** IRQ ANY ID */
|
||||
#define METAL_IRQ_ANY (-1)
|
||||
|
||||
/** IRQ state macro which will be passed to metal irq set state function
|
||||
* to indicate which state the caller want the IRQ to change to.
|
||||
*/
|
||||
#define METAL_IRQ_DISABLE 0U
|
||||
#define METAL_IRQ_ENABLE 1U
|
||||
|
||||
struct metal_irq_controller;
|
||||
|
||||
/**
|
||||
* @brief type of interrupt controller to set irq enable
|
||||
* @param[in] irq_cntr pointer to interrupt controller
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] enable IRQ state
|
||||
*/
|
||||
typedef void (*metal_irq_set_enable) (struct metal_irq_controller *irq_cntr,
|
||||
int irq, unsigned int enable);
|
||||
|
||||
/**
|
||||
* @brief type of controller specific registering interrupt function
|
||||
* @param[in] irq_cntr pointer to interrupt controller
|
||||
* @param[in] irq interrupt id
|
||||
* @param[in] hd interrupt handler
|
||||
* @param[in] arg argument which will be passed to the interrupt handler
|
||||
* @return 0 for success, negative value for failure
|
||||
*/
|
||||
typedef int (*metal_cntr_irq_register) (struct metal_irq_controller *irq_cntr,
|
||||
int irq, metal_irq_handler hd,
|
||||
void *arg);
|
||||
|
||||
/** Libmetal interrupt structure */
|
||||
struct metal_irq {
|
||||
metal_irq_handler hd; /**< Interrupt handler */
|
||||
void *arg; /**< Argument to pass to the interrupt handler */
|
||||
};
|
||||
|
||||
/** Libmetal interrupt controller structure */
|
||||
struct metal_irq_controller {
|
||||
int irq_base; /**< Start of IRQ number of the range managed by
|
||||
the IRQ controller */
|
||||
int irq_num; /**< Number of IRQs managed by the IRQ controller */
|
||||
void *arg; /**< Argument to pass to interrupt controller function */
|
||||
metal_irq_set_enable irq_set_enable; /**< function to set IRQ eanble */
|
||||
metal_cntr_irq_register irq_register; /**< function to register IRQ
|
||||
handler */
|
||||
struct metal_list node; /**< list node */
|
||||
struct metal_irq *irqs; /**< Array of IRQs managed by the controller */
|
||||
};
|
||||
|
||||
#define METAL_IRQ_CONTROLLER_DECLARE(_irq_controller, \
|
||||
_irq_base, _irq_num, \
|
||||
_arg, \
|
||||
_irq_set_enable, \
|
||||
_irq_register, \
|
||||
_irqs) \
|
||||
struct metal_irq_controller _irq_controller = { \
|
||||
.irq_base = _irq_base, \
|
||||
.irq_num = _irq_num, \
|
||||
.arg = _arg, \
|
||||
.irq_set_enable = _irq_set_enable, \
|
||||
.irq_register = _irq_register, \
|
||||
.irqs = _irqs,\
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief metal_irq_register_controller
|
||||
*
|
||||
* Register IRQ controller
|
||||
* This function will allocate IRQ ids if it was
|
||||
* not predefined in the irq controller. There is no
|
||||
* locking in the function, it is not supposed to be
|
||||
* called by multiple threads.
|
||||
*
|
||||
* @param[in] cntr Interrupt controller to register
|
||||
* @return 0 on success, or negative value for failure.
|
||||
*/
|
||||
int metal_irq_register_controller(struct metal_irq_controller *cntr);
|
||||
|
||||
/**
|
||||
* @brief metal_irq_handle
|
||||
*
|
||||
* Call registered IRQ handler
|
||||
*
|
||||
* @param[in] irq_data metal IRQ structure
|
||||
* @param[in] irq IRQ id which will be passed to handler
|
||||
* @return IRQ handler status
|
||||
*/
|
||||
static inline
|
||||
int metal_irq_handle(struct metal_irq *irq_data, int irq)
|
||||
{
|
||||
if (irq_data != NULL && irq_data->hd != NULL) {
|
||||
return irq_data->hd(irq, irq_data->arg);
|
||||
} else {
|
||||
return METAL_IRQ_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_IRQ__H__ */
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file list.h
|
||||
* @brief List primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_LIST__H__
|
||||
#define __METAL_LIST__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup list List Primitives
|
||||
* @{ */
|
||||
|
||||
struct metal_list {
|
||||
struct metal_list *next, *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
* METAL_INIT_LIST - used for initializing an list elmenet in a static struct
|
||||
* or global
|
||||
*/
|
||||
#define METAL_INIT_LIST(name) { .next = &name, .prev = &name }
|
||||
/*
|
||||
* METAL_DECLARE_LIST - used for defining and initializing a global or
|
||||
* static singleton list
|
||||
*/
|
||||
#define METAL_DECLARE_LIST(name) \
|
||||
struct metal_list name = METAL_INIT_LIST(name)
|
||||
|
||||
static inline void metal_list_init(struct metal_list *list)
|
||||
{
|
||||
list->next = list->prev = list;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_before(struct metal_list *node,
|
||||
struct metal_list *new_node)
|
||||
{
|
||||
new_node->prev = node->prev;
|
||||
new_node->next = node;
|
||||
new_node->next->prev = new_node;
|
||||
new_node->prev->next = new_node;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_after(struct metal_list *node,
|
||||
struct metal_list *new_node)
|
||||
{
|
||||
new_node->prev = node;
|
||||
new_node->next = node->next;
|
||||
new_node->next->prev = new_node;
|
||||
new_node->prev->next = new_node;
|
||||
}
|
||||
|
||||
static inline void metal_list_add_head(struct metal_list *list,
|
||||
struct metal_list *node)
|
||||
{
|
||||
metal_list_add_after(list, node);
|
||||
}
|
||||
|
||||
static inline void metal_list_add_tail(struct metal_list *list,
|
||||
struct metal_list *node)
|
||||
{
|
||||
metal_list_add_before(list, node);
|
||||
}
|
||||
|
||||
static inline int metal_list_is_empty(struct metal_list *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
static inline void metal_list_del(struct metal_list *node)
|
||||
{
|
||||
node->next->prev = node->prev;
|
||||
node->prev->next = node->next;
|
||||
node->next = node->prev = node;
|
||||
}
|
||||
|
||||
static inline struct metal_list *metal_list_first(struct metal_list *list)
|
||||
{
|
||||
return metal_list_is_empty(list) ? NULL : list->next;
|
||||
}
|
||||
|
||||
#define metal_list_for_each(list, node) \
|
||||
for ((node) = (list)->next; \
|
||||
(node) != (list); \
|
||||
(node) = (node)->next)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_LIST__H__ */
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <metal/log.h>
|
||||
#include <metal/sys.h>
|
||||
|
||||
void metal_default_log_handler(enum metal_log_level level,
|
||||
const char *format, ...)
|
||||
{
|
||||
#ifdef DEFAULT_LOGGER_ON
|
||||
char msg[1024];
|
||||
va_list args;
|
||||
static const char *level_strs[] = {
|
||||
"metal: emergency: ",
|
||||
"metal: alert: ",
|
||||
"metal: critical: ",
|
||||
"metal: error: ",
|
||||
"metal: warning: ",
|
||||
"metal: notice: ",
|
||||
"metal: info: ",
|
||||
"metal: debug: ",
|
||||
};
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
va_end(args);
|
||||
|
||||
if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG)
|
||||
level = METAL_LOG_EMERGENCY;
|
||||
|
||||
fprintf(stderr, "%s%s", level_strs[level], msg);
|
||||
#else
|
||||
(void)level;
|
||||
(void)format;
|
||||
#endif
|
||||
}
|
||||
|
||||
void metal_set_log_handler(metal_log_handler handler)
|
||||
{
|
||||
_metal.common.log_handler = handler;
|
||||
}
|
||||
|
||||
metal_log_handler metal_get_log_handler(void)
|
||||
{
|
||||
return _metal.common.log_handler;
|
||||
}
|
||||
|
||||
void metal_set_log_level(enum metal_log_level level)
|
||||
{
|
||||
_metal.common.log_level = level;
|
||||
}
|
||||
|
||||
enum metal_log_level metal_get_log_level(void)
|
||||
{
|
||||
return _metal.common.log_level;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file log.h
|
||||
* @brief Logging support for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_METAL_LOG__H__
|
||||
#define __METAL_METAL_LOG__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup logging Library Logging Interfaces
|
||||
* @{ */
|
||||
|
||||
/** Log message priority levels for libmetal. */
|
||||
enum metal_log_level {
|
||||
METAL_LOG_EMERGENCY, /**< system is unusable. */
|
||||
METAL_LOG_ALERT, /**< action must be taken immediately. */
|
||||
METAL_LOG_CRITICAL, /**< critical conditions. */
|
||||
METAL_LOG_ERROR, /**< error conditions. */
|
||||
METAL_LOG_WARNING, /**< warning conditions. */
|
||||
METAL_LOG_NOTICE, /**< normal but significant condition. */
|
||||
METAL_LOG_INFO, /**< informational messages. */
|
||||
METAL_LOG_DEBUG, /**< debug-level messages. */
|
||||
};
|
||||
|
||||
/** Log message handler type. */
|
||||
typedef void (*metal_log_handler)(enum metal_log_level level,
|
||||
const char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief Set libmetal log handler.
|
||||
* @param[in] handler log message handler.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern void metal_set_log_handler(metal_log_handler handler);
|
||||
|
||||
/**
|
||||
* @brief Get the current libmetal log handler.
|
||||
* @return Current log handler.
|
||||
*/
|
||||
extern metal_log_handler metal_get_log_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Set the level for libmetal logging.
|
||||
* @param[in] level log message level.
|
||||
*/
|
||||
extern void metal_set_log_level(enum metal_log_level level);
|
||||
|
||||
/**
|
||||
* @brief Get the current level for libmetal logging.
|
||||
* @return Current log level.
|
||||
*/
|
||||
extern enum metal_log_level metal_get_log_level(void);
|
||||
|
||||
/**
|
||||
* @brief Default libmetal log handler. This handler prints libmetal log
|
||||
* mesages to stderr.
|
||||
* @param[in] level log message level.
|
||||
* @param[in] format log message format string.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern void metal_default_log_handler(enum metal_log_level level,
|
||||
const char *format, ...);
|
||||
|
||||
|
||||
/**
|
||||
* Emit a log message if the log level permits.
|
||||
*
|
||||
* @param level Log level.
|
||||
* @param ... Format string and arguments.
|
||||
*/
|
||||
#define metal_log(level, ...) \
|
||||
((level <= _metal.common.log_level && _metal.common.log_handler) \
|
||||
? (void)_metal.common.log_handler(level, __VA_ARGS__) \
|
||||
: (void)0)
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/log.h>
|
||||
|
||||
#endif /* __METAL_METAL_LOG__H__ */
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file mutex.h
|
||||
* @brief Mutex primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_MUTEX__H__
|
||||
#define __METAL_MUTEX__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup mutex Mutex Interfaces
|
||||
* @{ */
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/mutex.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal mutex.
|
||||
* @param[in] mutex Mutex to initialize.
|
||||
*/
|
||||
static inline void metal_mutex_init(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_init(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize a libmetal mutex.
|
||||
* @param[in] mutex Mutex to deinitialize.
|
||||
*/
|
||||
static inline void metal_mutex_deinit(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_deinit(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to acquire a mutex
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
* @return 0 on failure to acquire, non-zero on success.
|
||||
*/
|
||||
static inline int metal_mutex_try_acquire(metal_mutex_t *mutex)
|
||||
{
|
||||
return __metal_mutex_try_acquire(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire a mutex
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
*/
|
||||
static inline void metal_mutex_acquire(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_acquire(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a previously acquired mutex.
|
||||
* @param[in] mutex Mutex to mutex.
|
||||
* @see metal_mutex_try_acquire, metal_mutex_acquire
|
||||
*/
|
||||
static inline void metal_mutex_release(metal_mutex_t *mutex)
|
||||
{
|
||||
__metal_mutex_release(mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checked if a mutex has been acquired.
|
||||
* @param[in] mutex mutex to check.
|
||||
* @see metal_mutex_try_acquire, metal_mutex_acquire
|
||||
*/
|
||||
static inline int metal_mutex_is_acquired(metal_mutex_t *mutex)
|
||||
{
|
||||
return __metal_mutex_is_acquired(mutex);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_MUTEX__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
add_subdirectory (${PROJECT_PROCESSOR})
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,4 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/atomic.h
|
||||
* @brief GCC specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_AARCH64_ATOMIC__H__
|
||||
#define __METAL_AARCH64_ATOMIC__H__
|
||||
|
||||
#endif /* __METAL_ARM_ATOMIC__H__ */
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primatives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_AARCH64_CPU__H__
|
||||
#define __METAL_AARCH64_CPU__H__
|
||||
|
||||
#define metal_cpu_yield() asm volatile("yield")
|
||||
|
||||
#endif /* __METAL_AARCH64_CPU__H__ */
|
|
@ -1,4 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/atomic.h
|
||||
* @brief GCC specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ARM_ATOMIC__H__
|
||||
#define __METAL_ARM_ATOMIC__H__
|
||||
|
||||
#endif /* __METAL_ARM_ATOMIC__H__ */
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primatives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ARM_CPU__H__
|
||||
#define __METAL_ARM_CPU__H__
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#endif /* __METAL_ARM_CPU__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Pinecone Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primitives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CEVA_CPU__H__
|
||||
#define __METAL_CEVA_CPU__H__
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#ifdef TEAKLITE4
|
||||
/*
|
||||
* The dummy implementation is enough here since
|
||||
* tl42x don't support the out of order and multi core
|
||||
*/
|
||||
#define __sync_synchronize()
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_CEVA_CPU__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Pinecone Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primitives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CSKY_CPU__H__
|
||||
#define __METAL_CSKY_CPU__H__
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#endif /* __METAL_CSKY_CPU__H__ */
|
|
@ -1,4 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file microblaze/atomic.h
|
||||
* @brief Microblaze specific atomic primitives for libmetal
|
||||
*/
|
||||
|
||||
#ifndef __METAL_MICROBLAZE_ATOMIC__H__
|
||||
#define __METAL_MICROBLAZE_ATOMIC__H__
|
||||
|
||||
#endif /* __METAL_MICROBLAZE_ATOMIC__H__ */
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primatives on microblaze platform.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_MICROBLAZE__H__
|
||||
#define __METAL_MICROBLAZE__H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <metal/atomic.h>
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#endif /* __METAL_MICROBLAZE__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Pinecone Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primitives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_RISCV_CPU__H__
|
||||
#define __METAL_RISCV_CPU__H__
|
||||
|
||||
#define metal_cpu_yield()
|
||||
|
||||
#endif /* __METAL_RISCV_CPU__H__ */
|
|
@ -1,4 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS atomic.h)
|
||||
collect (PROJECT_LIB_HEADERS cpu.h)
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,16 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file gcc/atomic.h
|
||||
* @brief GCC specific atomic primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_X86_64_ATOMIC__H__
|
||||
#define __METAL_X86_64_ATOMIC__H__
|
||||
|
||||
|
||||
#endif /* __METAL_X86_64_ATOMIC__H__ */
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file cpu.h
|
||||
* @brief CPU specific primatives
|
||||
*/
|
||||
|
||||
#ifndef __METAL_X86_64_CPU__H__
|
||||
#define __METAL_X86_64_CPU__H__
|
||||
|
||||
#define metal_cpu_yield() asm volatile("rep; nop")
|
||||
|
||||
#endif /* __METAL_X86_64_CPU__H__ */
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/shmem.c
|
||||
* @brief Generic libmetal shared memory handling.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <metal/assert.h>
|
||||
#include <metal/shmem.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/utilities.h>
|
||||
|
||||
int metal_shmem_register_generic(struct metal_generic_shmem *shmem)
|
||||
{
|
||||
/* Make sure that we can be found. */
|
||||
metal_assert(shmem->name && strlen(shmem->name) != 0);
|
||||
|
||||
/* Statically registered shmem regions cannot have a destructor. */
|
||||
metal_assert(!shmem->io.ops.close);
|
||||
|
||||
metal_list_add_tail(&_metal.common.generic_shmem_list,
|
||||
&shmem->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int metal_shmem_open_generic(const char *name, size_t size,
|
||||
struct metal_io_region **result)
|
||||
{
|
||||
struct metal_generic_shmem *shmem;
|
||||
struct metal_list *node;
|
||||
|
||||
metal_list_for_each(&_metal.common.generic_shmem_list, node) {
|
||||
shmem = metal_container_of(node, struct metal_generic_shmem, node);
|
||||
if (strcmp(shmem->name, name) != 0)
|
||||
continue;
|
||||
if (size > metal_io_region_size(&shmem->io))
|
||||
continue;
|
||||
*result = &shmem->io;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file shmem.h
|
||||
* @brief Shared memory primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SHMEM__H__
|
||||
#define __METAL_SHMEM__H__
|
||||
|
||||
#include <metal/io.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup shmem Shared Memory Interfaces
|
||||
* @{ */
|
||||
|
||||
/** Generic shared memory data structure. */
|
||||
struct metal_generic_shmem {
|
||||
const char *name;
|
||||
struct metal_io_region io;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Open a libmetal shared memory segment.
|
||||
*
|
||||
* Open a shared memory segment.
|
||||
*
|
||||
* @param[in] name Name of segment to open.
|
||||
* @param[in] size Size of segment.
|
||||
* @param[out] io I/O region handle, if successful.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*
|
||||
* @see metal_shmem_create
|
||||
*/
|
||||
extern int metal_shmem_open(const char *name, size_t size,
|
||||
struct metal_io_region **io);
|
||||
|
||||
/**
|
||||
* @brief Statically register a generic shared memory region.
|
||||
*
|
||||
* Shared memory regions may be statically registered at application
|
||||
* initialization, or may be dynamically opened. This interface is used for
|
||||
* static registration of regions. Subsequent calls to metal_shmem_open() look
|
||||
* up in this list of pre-registered regions.
|
||||
*
|
||||
* @param[in] shmem Generic shmem structure.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_shmem_register_generic(struct metal_generic_shmem *shmem);
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
|
||||
/**
|
||||
* @brief Open a statically registered shmem segment.
|
||||
*
|
||||
* This interface is meant for internal libmetal use within system specific
|
||||
* shmem implementations.
|
||||
*
|
||||
* @param[in] name Name of segment to open.
|
||||
* @param[in] size Size of segment.
|
||||
* @param[out] io I/O region handle, if successful.
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
int metal_shmem_open_generic(const char *name, size_t size,
|
||||
struct metal_io_region **result);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SHMEM__H__ */
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file sleep.h
|
||||
* @brief Sleep primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SLEEP__H__
|
||||
#define __METAL_SLEEP__H__
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/sleep.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup sleep Sleep Interfaces
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* @brief delay in microseconds
|
||||
* delay the next execution in the calling thread
|
||||
* fo usec microseconds.
|
||||
*
|
||||
* @param[in] usec microsecond intervals
|
||||
* @return 0 on success, non-zero for failures
|
||||
*/
|
||||
static inline int metal_sleep_usec(unsigned int usec)
|
||||
{
|
||||
return __metal_sleep_usec(usec);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SLEEP__H__ */
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <metal/atomic.h>
|
||||
#include <metal/irq.h>
|
||||
#include <metal/irq_controller.h>
|
||||
#include <metal/log.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/softirq.h>
|
||||
#include <metal/utilities.h>
|
||||
#include <string.h>
|
||||
|
||||
#define METAL_SOFTIRQ_NUM 64
|
||||
|
||||
#define METAL_SOFTIRQ_ARRAY_DECLARE(num) \
|
||||
static const int metal_softirq_num = num; \
|
||||
static struct metal_irq metal_softirqs[num]; \
|
||||
static atomic_char metal_softirq_pending[num]; \
|
||||
static atomic_char metal_softirq_enabled[num]; \
|
||||
|
||||
static int metal_softirq_avail = 0;
|
||||
METAL_SOFTIRQ_ARRAY_DECLARE(METAL_SOFTIRQ_NUM)
|
||||
|
||||
static void metal_softirq_set_enable(struct metal_irq_controller *cntr,
|
||||
int irq, unsigned int enable)
|
||||
{
|
||||
if (irq < cntr->irq_base ||
|
||||
irq >= (cntr->irq_base + cntr->irq_num)) {
|
||||
return;
|
||||
}
|
||||
|
||||
irq -= cntr->irq_base;
|
||||
if (enable == METAL_IRQ_ENABLE) {
|
||||
atomic_store(&metal_softirq_enabled[irq], 1);
|
||||
} else {
|
||||
atomic_store(&metal_softirq_enabled[irq], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static METAL_IRQ_CONTROLLER_DECLARE(metal_softirq_cntr,
|
||||
METAL_IRQ_ANY, METAL_SOFTIRQ_NUM,
|
||||
NULL,
|
||||
metal_softirq_set_enable, NULL,
|
||||
metal_softirqs)
|
||||
|
||||
void metal_softirq_set(int irq)
|
||||
{
|
||||
struct metal_irq_controller *cntr;
|
||||
|
||||
cntr = &metal_softirq_cntr;
|
||||
|
||||
if (irq < cntr->irq_base ||
|
||||
irq >= (cntr->irq_base + cntr->irq_num)) {
|
||||
return;
|
||||
}
|
||||
|
||||
irq -= cntr->irq_base;
|
||||
atomic_store(&metal_softirq_pending[irq], 1);
|
||||
}
|
||||
|
||||
int metal_softirq_init()
|
||||
{
|
||||
return metal_irq_register_controller(&metal_softirq_cntr);
|
||||
}
|
||||
|
||||
int metal_softirq_allocate(int num)
|
||||
{
|
||||
int irq_base;
|
||||
|
||||
if ((metal_softirq_avail + num) >= metal_softirq_num) {
|
||||
metal_log(METAL_LOG_ERROR, "No %d available soft irqs.\r\n",
|
||||
num);
|
||||
return -EINVAL;
|
||||
}
|
||||
irq_base = metal_softirq_avail;
|
||||
irq_base += metal_softirq_cntr.irq_base;
|
||||
metal_softirq_avail += num;
|
||||
return irq_base;
|
||||
}
|
||||
|
||||
void metal_softirq_dispatch()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < metal_softirq_num; i++) {
|
||||
struct metal_irq *irq;
|
||||
char is_pending = 1;
|
||||
|
||||
if (atomic_load(&metal_softirq_enabled[i]) != 0 &&
|
||||
atomic_compare_exchange_strong(&metal_softirq_pending[i],
|
||||
&is_pending, 0)) {
|
||||
irq = &metal_softirqs[i];
|
||||
(void)metal_irq_handle(irq,
|
||||
i + metal_softirq_cntr.irq_base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file softirq.h
|
||||
* @brief Soft Interrupt handling primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SOFTIRQ__H__
|
||||
#define __METAL_SOFTIRQ__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup soft irq Interrupt Handling Interfaces
|
||||
* @{ */
|
||||
|
||||
#include <metal/irq.h>
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_init
|
||||
*
|
||||
* Initialize libmetal soft IRQs controller
|
||||
*
|
||||
* @return 0 on success, or negative value for failure
|
||||
*/
|
||||
int metal_softirq_init();
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_dispatch
|
||||
*
|
||||
* Dispatch the pending soft IRQs
|
||||
*/
|
||||
void metal_softirq_dispatch();
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_allocate
|
||||
*
|
||||
* Allocate soft IRQs
|
||||
*
|
||||
* This function doesn't have any locking, it is not supposed
|
||||
* to be called by multiple threads.
|
||||
*
|
||||
* @param[in] num number of soft irqs requested
|
||||
* @return soft irq base for success, or negative value for failure
|
||||
*/
|
||||
int metal_softirq_allocate(int num);
|
||||
|
||||
/**
|
||||
* @brief metal_softirq_set
|
||||
*
|
||||
* Set soft IRQ to pending
|
||||
*
|
||||
* @param[in] irq soft IRQ ID to set
|
||||
*/
|
||||
void metal_softirq_set(int irq);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SOFTIRQ__H__ */
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file spinlock.h
|
||||
* @brief Spinlock primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SPINLOCK__H__
|
||||
#define __METAL_SPINLOCK__H__
|
||||
|
||||
#include <metal/atomic.h>
|
||||
#include <metal/cpu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup spinlock Spinlock Interfaces
|
||||
* @{ */
|
||||
struct metal_spinlock {
|
||||
atomic_flag v;
|
||||
};
|
||||
|
||||
/** Static metal spinlock initialization. */
|
||||
#define METAL_SPINLOCK_INIT {ATOMIC_FLAG_INIT}
|
||||
|
||||
/**
|
||||
* @brief Initialize a libmetal spinlock.
|
||||
* @param[in] slock Spinlock to initialize.
|
||||
*/
|
||||
static inline void metal_spinlock_init(struct metal_spinlock *slock)
|
||||
{
|
||||
atomic_flag_clear(&slock->v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Acquire a spinlock.
|
||||
* @param[in] slock Spinlock to acquire.
|
||||
* @see metal_spinlock_release
|
||||
*/
|
||||
static inline void metal_spinlock_acquire(struct metal_spinlock *slock)
|
||||
{
|
||||
while (atomic_flag_test_and_set(&slock->v)) {
|
||||
metal_cpu_yield();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a previously acquired spinlock.
|
||||
* @param[in] slock Spinlock to release.
|
||||
* @see metal_spinlock_acquire
|
||||
*/
|
||||
static inline void metal_spinlock_release(struct metal_spinlock *slock)
|
||||
{
|
||||
atomic_flag_clear(&slock->v);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SPINLOCK__H__ */
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file sys.h
|
||||
* @brief System primitives for libmetal.
|
||||
* @brief Top level include internal to libmetal library code.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_SYS__H__
|
||||
#define __METAL_SYS__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <metal/log.h>
|
||||
#include <metal/list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup system Top Level Interfaces
|
||||
* @{ */
|
||||
|
||||
/** Physical address type. */
|
||||
typedef unsigned long metal_phys_addr_t;
|
||||
|
||||
/** Interrupt request number. */
|
||||
typedef int metal_irq_t;
|
||||
|
||||
/** Bad offset into shared memory or I/O region. */
|
||||
#define METAL_BAD_OFFSET ((unsigned long)-1)
|
||||
|
||||
/** Bad physical address value. */
|
||||
#define METAL_BAD_PHYS ((metal_phys_addr_t)-1)
|
||||
|
||||
/** Bad virtual address value. */
|
||||
#define METAL_BAD_VA ((void *)-1)
|
||||
|
||||
/** Bad IRQ. */
|
||||
#define METAL_BAD_IRQ ((metal_irq_t)-1)
|
||||
|
||||
/**
|
||||
* Initialization configuration for libmetal.
|
||||
*/
|
||||
struct metal_init_params {
|
||||
|
||||
/** log message handler (defaults to stderr). */
|
||||
metal_log_handler log_handler;
|
||||
|
||||
/** default log message level (defaults to emergency). */
|
||||
enum metal_log_level log_level;
|
||||
};
|
||||
|
||||
/**
|
||||
* System independent runtime state for libmetal. This is part of a system
|
||||
* specific singleton data structure (@see _metal).
|
||||
*/
|
||||
struct metal_common_state {
|
||||
/** Current log level. */
|
||||
enum metal_log_level log_level;
|
||||
|
||||
/** Current log handler (null for none). */
|
||||
metal_log_handler log_handler;
|
||||
|
||||
/** List of registered buses. */
|
||||
struct metal_list bus_list;
|
||||
|
||||
/** Generic statically defined shared memory segments. */
|
||||
struct metal_list generic_shmem_list;
|
||||
|
||||
/** Generic statically defined devices. */
|
||||
struct metal_list generic_device_list;
|
||||
};
|
||||
|
||||
struct metal_state;
|
||||
|
||||
#include <metal/system/@PROJECT_SYSTEM@/sys.h>
|
||||
|
||||
#ifndef METAL_INIT_DEFAULTS
|
||||
#define METAL_INIT_DEFAULTS \
|
||||
{ \
|
||||
.log_handler = metal_default_log_handler, \
|
||||
.log_level = METAL_LOG_INFO, \
|
||||
}
|
||||
#endif
|
||||
|
||||
/** System specific runtime data. */
|
||||
extern struct metal_state _metal;
|
||||
|
||||
/**
|
||||
* @brief Initialize libmetal.
|
||||
*
|
||||
* Initialize the libmetal library.
|
||||
*
|
||||
* @param[in] params Initialization params (@see metal_init_params).
|
||||
*
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*
|
||||
* @see metal_finish
|
||||
*/
|
||||
extern int metal_init(const struct metal_init_params *params);
|
||||
|
||||
/**
|
||||
* @brief Shutdown libmetal.
|
||||
*
|
||||
* Shutdown the libmetal library, and release all reserved resources.
|
||||
*
|
||||
* @see metal_init
|
||||
*/
|
||||
extern void metal_finish(void);
|
||||
|
||||
#ifdef METAL_INTERNAL
|
||||
|
||||
/**
|
||||
* @brief libmetal system initialization.
|
||||
*
|
||||
* This function initializes libmetal on Linux or Generic platforms. This
|
||||
* involves obtaining necessary pieces of system information (sysfs mount path,
|
||||
* page size, etc.).
|
||||
*
|
||||
* @param[in] params Initialization parameters (@see metal_init_params).
|
||||
* @return 0 on success, or -errno on failure.
|
||||
*/
|
||||
extern int metal_sys_init(const struct metal_init_params *params);
|
||||
|
||||
/**
|
||||
* @brief libmetal system shutdown.
|
||||
*
|
||||
* This function shuts down and releases resources held by libmetal Linux or
|
||||
* Generic platform layers.
|
||||
*
|
||||
* @see metal_sys_init
|
||||
*/
|
||||
extern void metal_sys_finish(void);
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_SYS__H__ */
|
|
@ -1,3 +0,0 @@
|
|||
add_subdirectory (${PROJECT_SYSTEM})
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,24 +0,0 @@
|
|||
collect (PROJECT_LIB_HEADERS alloc.h)
|
||||
collect (PROJECT_LIB_HEADERS assert.h)
|
||||
collect (PROJECT_LIB_HEADERS cache.h)
|
||||
collect (PROJECT_LIB_HEADERS condition.h)
|
||||
collect (PROJECT_LIB_HEADERS io.h)
|
||||
collect (PROJECT_LIB_HEADERS irq.h)
|
||||
collect (PROJECT_LIB_HEADERS log.h)
|
||||
collect (PROJECT_LIB_HEADERS mutex.h)
|
||||
collect (PROJECT_LIB_HEADERS sleep.h)
|
||||
collect (PROJECT_LIB_HEADERS sys.h)
|
||||
|
||||
collect (PROJECT_LIB_SOURCES condition.c)
|
||||
collect (PROJECT_LIB_SOURCES device.c)
|
||||
collect (PROJECT_LIB_SOURCES init.c)
|
||||
collect (PROJECT_LIB_SOURCES io.c)
|
||||
collect (PROJECT_LIB_SOURCES irq.c)
|
||||
collect (PROJECT_LIB_SOURCES shmem.c)
|
||||
collect (PROJECT_LIB_SOURCES time.c)
|
||||
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_MACHINE})
|
||||
add_subdirectory(${PROJECT_MACHINE})
|
||||
endif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_MACHINE})
|
||||
|
||||
# vim: expandtab:ts=2:sw=2:smartindent
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file freertos/alloc.c
|
||||
* @brief FreeRTOS libmetal memory allocattion definitions.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_ALLOC__H__
|
||||
#error "Include metal/alloc.h instead of metal/freertos/alloc.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_FREERTOS_ALLOC__H__
|
||||
#define __METAL_FREERTOS_ALLOC__H__
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void *metal_allocate_memory(unsigned int size)
|
||||
{
|
||||
return (pvPortMalloc(size));
|
||||
}
|
||||
|
||||
static inline void metal_free_memory(void *ptr)
|
||||
{
|
||||
vPortFree(ptr);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_FREERTOS_ALLOC__H__ */
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file assert.h
|
||||
* @brief FreeRTOS assertion support.
|
||||
*/
|
||||
#ifndef __METAL_ASSERT__H__
|
||||
#error "Include metal/assert.h instead of metal/freertos/assert.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_FREERTOS_ASSERT__H__
|
||||
#define __METAL_FREERTOS_ASSERT__H__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* @brief Assertion macro for FreeRTOS applications.
|
||||
* @param cond Condition to evaluate.
|
||||
*/
|
||||
#define metal_sys_assert(cond) assert(cond)
|
||||
|
||||
#endif /* __METAL_FREERTOS_ASSERT__H__ */
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file freertos/cache.h
|
||||
* @brief FreeRTOS cache operation primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CACHE__H__
|
||||
#error "Include metal/cache.h instead of metal/freertos/cache.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_FREERTOS_CACHE__H__
|
||||
#define __METAL_FREERTOS_CACHE__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void metal_machine_cache_flush(void *addr, unsigned int len);
|
||||
extern void metal_machine_cache_invalidate(void *addr, unsigned int len);
|
||||
|
||||
static inline void __metal_cache_flush(void *addr, unsigned int len)
|
||||
{
|
||||
metal_machine_cache_flush(addr, len);
|
||||
}
|
||||
|
||||
static inline void __metal_cache_invalidate(void *addr, unsigned int len)
|
||||
{
|
||||
metal_machine_cache_invalidate(addr, len);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_FREERTOS_CACHE__H__ */
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/condition.c
|
||||
* @brief Generic libmetal condition variable handling.
|
||||
*/
|
||||
|
||||
#include <metal/condition.h>
|
||||
|
||||
int metal_condition_wait(struct metal_condition *cv,
|
||||
metal_mutex_t *m)
|
||||
{
|
||||
/* TODO: Implement condition variable for FreeRTOS */
|
||||
(void)cv;
|
||||
(void)m;
|
||||
return 0;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file generic/condition.h
|
||||
* @brief Generic condition variable primitives for libmetal.
|
||||
*/
|
||||
|
||||
#ifndef __METAL_CONDITION__H__
|
||||
#error "Include metal/condition.h instead of metal/freertos/condition.h"
|
||||
#endif
|
||||
|
||||
#ifndef __METAL_FREERTOS_CONDITION__H__
|
||||
#define __METAL_FREERTOS_CONDITION__H__
|
||||
|
||||
#include <metal/atomic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct metal_condition {
|
||||
metal_mutex_t *m; /**< mutex.
|
||||
The condition variable is attached to
|
||||
this mutex when it is waiting.
|
||||
It is also used to check correctness
|
||||
in case there are multiple waiters. */
|
||||
|
||||
atomic_int v; /**< condition variable value. */
|
||||
};
|
||||
|
||||
/** Static metal condition variable initialization. */
|
||||
#define METAL_CONDITION_INIT { NULL, ATOMIC_VAR_INIT(0) }
|
||||
|
||||
static inline void metal_condition_init(struct metal_condition *cv)
|
||||
{
|
||||
/* TODO: Implement condition variable for FreeRTOS */
|
||||
(void)cv;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int metal_condition_signal(struct metal_condition *cv)
|
||||
{
|
||||
/* TODO: Implement condition variable for FreeRTOS */
|
||||
(void)cv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int metal_condition_broadcast(struct metal_condition *cv)
|
||||
{
|
||||
/* TODO: Implement condition variable for FreeRTOS */
|
||||
(void)cv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __METAL_FREERTOS_CONDITION__H__ */
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* @file freertos/device.c
|
||||
* @brief FreeRTOS device operations.
|
||||
*/
|
||||
|
||||
#include <metal/device.h>
|
||||
#include <metal/sys.h>
|
||||
#include <metal/utilities.h>
|
||||
|
||||
int metal_generic_dev_sys_open(struct metal_device *dev)
|
||||
{
|
||||
struct metal_io_region *io;
|
||||
unsigned i;
|
||||
|
||||
/* map I/O memory regions */
|
||||
for (i = 0; i < dev->num_regions; i++) {
|
||||
io = &dev->regions[i];
|
||||
if (!io->size)
|
||||
break;
|
||||
metal_sys_io_mem_map(io);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue