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