1# libmetal 2 3## Overview 4 5Libmetal provides common user APIs to access devices, handle device interrupts 6and request memory across the following operating environments: 7 * Linux user space (based on UIO and VFIO support in the kernel) 8 * RTOS (with and without virtual memory) 9 * Bare-metal environments 10 11For more details on the framework please refer to the 12[OpenAMP Docs](https://openamp.readthedocs.io/en/latest/). 13 14## Project configuration 15 16The configuration phase begins when the user invokes CMake. CMake begins by 17processing the CMakeLists.txt file and the cmake directory. Some cmake options 18are available to help user to customize the libmetal to their own project. 19 20* **WITH_DOC** (default ON): Build with documentation. Add -DWITH_DOC=OFF in 21cmake command line to disable. 22* **WITH_EXAMPLES** (default ON): Build with application examples. Add 23-DWITH_DOC=OFF in cmake command line to disable the option. 24* **WITH_TESTS** (default ON): Build with application tests. Add -DWITH_DOC=OFF 25in cmake command line to disable the option. 26* **WITH_DEFAULT_LOGGER** (default ON): Build with default trace logger. Add 27-DWITH_DEFAULT_LOGGER=OFF in cmake command line to disable the option. 28* **WITH_SHARED_LIB** (default ON): Generate a shared library. Add 29-DWITH_SHARED_LIB=OFF in cmake command line to disable the option. 30* **WITH_STATIC_LIB** (default ON): Generate a static library. Add 31-DWITH_STATIC_LIB=OFF in cmake command line to disable the option. 32* **WITH_ZEPHYR** (default OFF): Build for Zephyr environment. Add 33-DWITH_ZEPHYR=ON in cmake command line to enable the the option. 34 35## Build Steps 36 37### Building for Linux Host 38``` 39 $ git clone https://github.com/OpenAMP/libmetal.git 40 $ mkdir -p libmetal/<build directory> 41 $ cd libmetal/<build directory> 42 $ cmake .. 43 $ make VERBOSE=1 DESTDIR=<libmetal install location> install 44``` 45 46### Cross Compiling for Linux Target 47 48Use [meta-openamp](https://github.com/openamp/meta-openamp) to build 49libmetal library. 50 51Use package `libmetal` in your Yocto config file. 52 53### Building for Baremetal 54 55To build on baremetal, you will need to provide a toolchain file. Here is an 56example toolchain file: 57``` 58 set (CMAKE_SYSTEM_PROCESSOR "arm" CACHE STRING "") 59 set (MACHINE "zynqmp_r5" CACHE STRING "") 60 61 set (CROSS_PREFIX "armr5-none-eabi-" CACHE STRING "") 62 set (CMAKE_C_FLAGS "-mfloat-abi=soft -mcpu=cortex-r5 -Wall -Werror -Wextra \ 63 -flto -Os -I/ws/xsdk/r5_0_bsp/psu_cortexr5_0/include" CACHE STRING "") 64 65 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") 66 SET(CMAKE_AR "gcc-ar" CACHE STRING "") 67 SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>") 68 SET(CMAKE_C_ARCHIVE_FINISH true) 69 70 include (cross-generic-gcc) 71``` 72* Note: other toolchain files can be found in the `cmake/platforms/` directory. 73* Compile with your toolchain file. 74``` 75 $ mkdir -p build-libmetal 76 $ cd build-libmetal 77 $ cmake <libmetal_source> -DCMAKE_TOOLCHAIN_FILE=<toolchain_file> 78 $ make VERBOSE=1 DESTDIR=<libmetal_install> install 79``` 80* Note: When building baremetal for Xilinx 2018.3 or earlier environments, 81add -DXILINX_PRE_V2019 to your CMake invocation. This will include the 82xilmem and xilstandalone libraries in your build. These libraries were 83removed in 2019.1. 84 85### Building for Zephyr 86 87The [zephyr-libmetal](https://github.com/zephyrproject-rtos/libmetal) 88implements the libmetal for the Zephyr project. It is mainly a fork of this 89repository, with some add-ons for integration in the Zephyr project. 90 91Following instruction is only to be able to run test application on a QEMU 92running a Zephyr environment. 93 94As Zephyr uses CMake, we build libmetal library and test application as targets 95of Zephyr CMake project. Here is how to build libmetal for Zephyr: 96``` 97 $ export ZEPHYR_TOOLCHAIN_VARIANT=zephyr 98 $ export ZEPHYR_SDK_INSTALL_DIR=<where Zephyr SDK is installed> 99 $ source <git_clone_zephyr_project_source_root>/zephyr-env.sh 100 101 $ cmake <libmetal_source_root> -DWITH_ZEPHYR=on -DBOARD=qemu_cortex_m3 \ 102 [-DWITH_TESTS=on] 103 $ make VERBOSE=1 all 104 # If we have turned on tests with "-DWITH_TESTS=on" when we run cmake, 105 # we launch libmetal test on Zephyr QEMU platform as follows: 106 $ make VERBOSE=1 run 107``` 108 109## Interfaces 110 111The following subsections give an overview of interfaces provided by libmetal. 112 113### Platform and OS Independent Utilities 114 115These interfaces do not need to be ported across to new operating systems. 116 117#### I/O 118 119The libmetal I/O region abstraction provides access to memory mapped I/O and 120shared memory regions. This includes: 121 * primitives to read and write memory with ordering constraints, and 122 * ability to translate between physical and virtual addressing on systems 123 that support virtual memory. 124 125#### Log 126 127The libmetal logging interface is used to plug log messages generated by 128libmetal into application specific logging mechanisms (e.g. syslog). This 129also provides basic message prioritization and filtering mechanisms. 130 131#### List 132 133This is a simple doubly linked list implementation used internally within 134libmetal, and also available for application use. 135 136#### Other Utilities 137 138The following utilities are provided in lib/utilities.h: 139 * Min/max, round up/down, etc. 140 * Bitmap operations 141 * Helper to compute container structure pointers 142 * ... and more ... 143 144#### Version 145 146The libmetal version interface allows user to get the version of the library. 147The version increment follows the set of rule proposed in 148[Semantic Versioning specification](https://semver.org/). 149 150### Top Level Interfaces 151 152The users will need to call two top level interfaces to use libmetal APIs: 153 * metal_init - initialize the libmetal resource 154 * metal_finish - release libmetal resource 155 156Each system needs to have their own implementation inside libmetal for these 157two APIs to call: 158 * metal_sys_init 159 * metal_sys_finish 160 161For the current release, libmetal provides Linux userspace and bare-metal 162implementation for metal_sys_init and metal_sys_finish. 163 164For Linux userspace, metal_sys_init sets up a table for available shared pages, 165checks whether UIO/VFIO drivers are avail, and starts interrupt handling thread. 166 167Please note that on Linux, to access device's memory that is not page aligned, 168an offset has to be added to the pointer returned by mmap(). This `offset`, 169although it can be read from the device tree property exposed by the uio driver, 170is not handled yet by the library. 171 172For bare-metal, metal_sys_init and metal_sys_finish just returns. 173 174### Atomics 175 176The libmetal atomic operations API is consistent with the C11/C++11 stdatomics 177interface. The stdatomics interface is commonly provided by recent toolchains 178including GCC and LLVM/Clang. When porting to a different toolchain, it may be 179necessary to provide an stdatomic compatible implementation if the toolchain 180does not already provide one. 181 182### Alloc 183 184libmetal provides memory allocation and release APIs. 185 186### Locking 187 188libmetal provides the following locking APIs. 189 190#### Mutex 191 192libmetal has a generic mutex implementation which is a busy wait. It is 193recommended to have OS specific implementation for mutex. 194 195The Linux userspace mutex implementation uses futex to wait for the lock 196and wakeup a waiter. 197 198#### Condition Variable 199libmetal condition variable APIs provide "wait" for user applications to wait 200on some condition to be met, and "signal" to indicate a particular even occurs. 201 202#### Spinlock 203libmetal spinlock APIs provides busy waiting mechanism to acquire a lock. 204 205### Shmem 206 207libmetal has a generic static shared memory implementation. If your OS has a 208global shared memory allocation, you will need to port it for the OS. 209 210The Linux userspace shmem implementation uses libhugetlbfs to support huge page 211sizes. 212 213### Bus and Device Abstraction 214 215libmetal has a static generic implementation. If your OS has a driver model 216implementation, you will need to port it for the OS. 217 218The Linux userspace abstraction binds the devices to UIO or VFIO driver. The 219user applications specify which device to use, e.g. bus "platform" bus, device 220"f8000000.slcr", and then the abstraction will check if platform UIO driver or 221platform VFIO driver is there. If platform VFIO driver exists, it will bind the 222device to the platform VFIO driver, otherwise, if UIO driver exists, it will 223bind the device to the platform UIO driver. 224 225The VFIO support is not yet implemented. 226 227### Interrupt 228 229libmetal provides APIs to register an interrupt, disable interrupts and restore 230interrupts. 231 232The Linux userspace implementation will use a thread to call select() function 233to listen to the file descriptors of the devices to see if there is an interrupt 234triggered. If there is an interrupt triggered, it will call the interrupt 235handler registered by the user application. 236 237### Cache 238 239libmetal provides APIs to flush and invalidate caches. 240 241The cache APIs for Linux userspace are empty functions for now as cache 242operations system calls are not available for all architectures. 243 244### DMA 245 246libmetal DMA APIs provide DMA map and unmap implementation. 247 248After calling DMA map, the DMA device will own the memory. 249After calling DMA unmap, the cpu will own the memory. 250 251For Linux userspace, it only supports to use UIO device memory as DMA 252memory for this release. 253 254### Time 255libmetal time APIs provide getting timestamp implementation. 256 257### Sleep 258libmetal sleep APIs provide getting delay execution implementation. 259 260### Compiler 261 262This API is for compiler dependent functions. For this release, there is only 263a GCC implementation, and compiler specific code is limited to atomic 264operations. 265 266## How to contribute 267 268As an open-source project, we welcome and encourage the community to submit 269patches directly to the project. As a contributor you should be familiar with 270common developer tools such as Git and CMake, and platforms such as GitHub. 271 272Then following points should be rescpected to facilitate the review process. 273 274### Licencing 275 276Code is contributed to OpenAMP under a number of licenses, but all code must be 277compatible with version the 278[BSD License](https://github.com/OpenAMP/libmetal/blob/master/LICENSE.md), which 279is the license covering the OpenAMP distribution as a whole. In practice, use 280the following tag instead of the full license text in the individual files: 281 282 ``` 283 SPDX-License-Identifier: BSD-3-Clause 284 ``` 285### Signed-off-by 286 287Commit messages must contain Signed-off-by: line and your email must match the 288change authorship information. Make sure your .gitconfig is set up correctly: 289 290 ``` 291 git config --global user.name "first-name Last-Namer" 292 git config --global user.email "yourmail@company.com" 293 ``` 294 295### gitlint 296 297Before you submit a pull request to the project, verify your commit messages 298meet the requirements. The check can be performed locally using the the gitlint 299command. 300 301Run gitlint locally in your tree and branch where your patches have been 302committed: 303 304 ```gitlint``` 305 306Note, gitlint only checks HEAD (the most recent commit), so you should run it 307after each commit, or use the --commits option to specify a commit range 308covering all the development patches to be submitted. 309 310### Code style 311 312In general, follow the Linux kernel coding style, with the following exceptions: 313 314* Use /** */ for doxygen comments that need to appear in the documentation. 315 316The Linux kernel GPL-licensed tool checkpatch is used to check coding style 317conformity. Checkpatch is available in the scripts directory. 318 319To check your \<n\> commits in your git branch: 320 321 ``` 322 ./scripts/checkpatch.pl --strict -g HEAD-<n> 323 324 ``` 325### Send a pull request 326 327We use standard GitHub mechanism for pull request. Please refer to GitHub 328documentation for help. 329 330## Communication and Collaboration 331 332[Subscribe](https://lists.openampproject.org/mailman3/lists/openamp-rp.lists.openampproject.org/) 333to the OpenAMP mailing list (openamp-rp@lists.openampproject.org). 334