Soby Mathew | b4c6df4 | 2022-11-09 11:13:29 +0000 | [diff] [blame] | 1 | .. SPDX-License-Identifier: BSD-3-Clause |
| 2 | .. SPDX-FileCopyrightText: Copyright TF-RMM Contributors. |
| 3 | |
| 4 | .. Custom color scheme for this document |
| 5 | .. raw:: html |
| 6 | |
| 7 | <style> .comp {color:DarkMagenta} </style> |
| 8 | |
| 9 | .. role:: comp |
| 10 | |
| 11 | ##################################### |
| 12 | RMM Folder and Component organization |
| 13 | ##################################### |
| 14 | |
| 15 | ********************************** |
| 16 | Root Level Folders and Components |
| 17 | ********************************** |
| 18 | |
| 19 | The root level folder structure of the RMM project is as given below. |
| 20 | |
| 21 | :: |
| 22 | |
| 23 | ┌── cmake |
| 24 | ├── configs |
| 25 | ├── docs |
| 26 | ├── drivers |
| 27 | ├── ext |
| 28 | ├── lib |
| 29 | ├── plat |
| 30 | ├── runtime |
| 31 | ├── toolchains |
| 32 | └── tools |
| 33 | |
| 34 | The RMM functionality is implemented by files in :comp:`lib`, :comp:`ext`, |
| 35 | :comp:`drivers`, :comp:`plat` and :comp:`runtime`. Each of these folders |
| 36 | corresponds to a :comp:`component` in the project. Every component has a |
| 37 | defined role in implementing the RMM functionality and can in-turn be |
| 38 | composed of sub-components of the same role. The components have |
| 39 | their own CMakelists.txt file and a defined public API which is |
| 40 | exported via the public interface of the component to its dependent |
| 41 | users. The :comp:`runtime` component is an exception as it does not |
| 42 | have a public API. |
| 43 | |
| 44 | The dependency relationship between the top level components is shown |
| 45 | below : |
| 46 | |
| 47 | |Dependency Diagram| |
| 48 | |
| 49 | Each component and its role is described below : |
| 50 | |
| 51 | * **lib** : This component is a library of re-usable and architectural |
| 52 | code which needs to be used by other components. |
| 53 | The :comp:`lib` component is composed of several sub-components |
| 54 | and every sub-component has a public API which is exported via its |
| 55 | public interface. The functionality implemented by the sub-component |
| 56 | is not platform specific although there could be specific static |
| 57 | configuration or platform specific data provided via defined public |
| 58 | interface. All of the sub-components in :comp:`lib` are combined into |
| 59 | a single archive file which is then included in the build. |
| 60 | |
| 61 | The :comp:`lib` component depends on :comp:`ext` and :comp:`plat` |
| 62 | components. All other components in the project depend on :comp:`lib`. |
| 63 | |
| 64 | * **ext** : This component is meant for external source dependencies of |
| 65 | the project. The sub folders are external open source projects configured |
| 66 | as git submodules. The :comp:`ext` component is only allowed to depend on |
| 67 | libc implementation in :comp:`lib` component. |
| 68 | |
| 69 | * **plat** : This component implements the platform abstraction layer or |
| 70 | platform layer for short. The platform layer has the following |
| 71 | responsibilities: |
| 72 | |
| 73 | #. Implement the platform porting API as defined in platform_api.h. |
| 74 | #. Do any necessary platform specific initialization in the platform layer. |
| 75 | #. Initialize :comp:`lib` sub-components with platform specific data. |
| 76 | #. Include any platform specific drivers from the :comp:`drivers` folder |
| 77 | and initialize them as necessary. |
| 78 | |
| 79 | Every platform or a family of related platforms is expected to have a |
| 80 | folder in :comp:`plat` and only one such folder corresponding to the |
| 81 | platform will be included in the build. The :comp:`plat` component depends |
| 82 | on :comp:`lib` and any platform specific drivers in :comp:`drivers`. |
| 83 | |
| 84 | * **drivers** : The platform specific drivers are implemented in this |
| 85 | component. Only the `plat` component is allowed to access these drivers |
| 86 | via its public interface. |
| 87 | |
| 88 | * **runtime** : This component implements generic RMM functionality which |
| 89 | does not need to be shared across different components. The :comp:`runtime` |
| 90 | component does not have a public interface and is not a dependency for any |
| 91 | other component. The :comp:`runtime` is compiled into the binary |
| 92 | ``rmm.img`` after linking with other components in the build. |
| 93 | |
| 94 | |
| 95 | ********************************** |
| 96 | Component File and Cmake Structure |
| 97 | ********************************** |
| 98 | |
| 99 | The below figure shows the folder organization of a typical |
| 100 | component (or sub-component) |
| 101 | |
| 102 | :: |
| 103 | |
| 104 | component x |
| 105 | ├── include |
| 106 | | └── public.h |
| 107 | ├── src |
| 108 | | ├── private_a.h |
| 109 | | └── src_a.c |
| 110 | ├── tests |
| 111 | | └── test.cpp |
| 112 | └── CMakeLists.txt |
| 113 | |
| 114 | The ``include`` folder contains the headers exposing the public API of the |
| 115 | component. The ``src`` contains the private headers and implementation |
| 116 | of the intended functionality. The ``tests`` contains the tests for the |
| 117 | component and the ``CMakeLists.txt`` defines the build and |
| 118 | inheritance rules. |
| 119 | |
| 120 | A typical component ``CMakeLists.txt`` has the following structure : |
| 121 | |
| 122 | .. code-block:: CMake |
| 123 | |
| 124 | add_library(comp-x) |
| 125 | |
| 126 | # Define any static config option for this component. |
| 127 | arm_config_option() |
| 128 | |
| 129 | # Pass the config option to the source files as a compile |
| 130 | # option. |
| 131 | target_compile_definitions() |
| 132 | |
| 133 | # Specify any private dependencies of the component. These are not |
| 134 | # inherited by child dependencies. |
| 135 | target_link_libraries(comp-x |
| 136 | PRIVATE xxx) |
| 137 | |
| 138 | # Specify any private dependencies of the component. These are |
| 139 | # inherited by child dependencies and are usually included in |
| 140 | # public API header of the component. |
| 141 | target_link_libraries(comp-x |
| 142 | PUBLIC yyy) |
| 143 | |
| 144 | # Export public API via public interface of this component |
| 145 | target_include_directories(comp-x |
| 146 | PUBLIC "include") |
| 147 | |
| 148 | # Specify any private headers to be included for compilation |
| 149 | # of this component. |
| 150 | target_include_directories(comp-x |
| 151 | PRIVATE "src") |
| 152 | |
| 153 | # Specify source files for component |
| 154 | target_sources(comp-x |
| 155 | PRIVATE xxx) |
| 156 | |
| 157 | .. |Dependency Diagram| image:: ./diagrams/root_component_dependency.drawio.png |