blob: 9f79999310caa97c6ca2adabbc0a7a243ebe2feb [file] [log] [blame]
Julian Hall86ae7492022-09-02 15:56:00 +01001Service Deployment Model
2========================
3A goal of the Trusted Services project is to provide a toolbox of reusable service components
4that can be deployed across a wide range of platforms. The project structure promotes reuse by
5grouping related source files into subdirectories that represent reusable components. Components
6may be configured and combined in different ways to meet the needs of platform integrators who
7aim to create firmware with the right features and tradeoffs for their products.
8
9Within the TS project structure, build files that combine and configure components to create
10deployable firmware images reside under the deployments top-level directory. Beneath the
11deployments parent are sub-directories concerned with building and deploying different
12applications. Applications can generally be classified as one of the following:
13
14 - Service providers
15 - Test suites
16 - Libraries
17 - Development support applications
18
19This page is mainly concerned with describing the conventions used to enable service providers
20to be deployed in different environments, on different platforms and with different capabilities.
21The conventions aim to minimize build definition duplication between alternative deployments
22while offering sufficient flexibility to customize capabilities and support different platforms.
23The service deployment model borrows from a pattern used for deploying cloud services where There
24is a similar requirement for deployment flexibility.
25
26Ports and Adapters Architecture
27-------------------------------
28An application is decoupled from any particular environment via a set of interfaces that reflect
29the needs of the application. This model conforms to the ports and adapters architectural
30pattern that aims to avoid tight coupling between application components and any particular
31environment. This pattern, also known as the hexagonal architecture, is often illustrated as a
32hexagonal cell with the application on the inside and the platform on the outside.
33
34The following diagram illustrates how ports and adapters is applied in the trusted services
35project to provide a model for service provider deployment.
36
37.. image:: image/TSportabilityModel.svg
38
39This deployment model has the following characteristics:
40
41 - The application is decoupled from the environment by a set of virtual interfaces (ports)
42 that reflect the needs of the application.
43 - Ports are realized by a set of adapters. An adapter may:
44
45 * Use a service/device provided by the platform or environment.
46 * Communicate with another service provider.
47 * Provide a self-contained implementation.
48 - The set of adapters that the application depends on represents the infrastructure that is
49 needed to support the application.
50 - Different infrastructure realizations may be needed for different deployments of the same
51 service provider.
52
53Service Deployment Structure
54----------------------------
55By convention, the directory structure for service provider deployments reflects the layers in
56the ports and adapters architecture. The following dependency diagram illustrates the set of
57relationships that exist for a fully defined deployment:
58
59.. uml:: uml/ServiceDeploymentDependencies.puml
60
61To avoid undesirable build definition duplication when adding new deployments of an application,
62the directory structure used to organize files related to different deployments should reflect
63the above model. The following table lists reusable build components that may be used across
64different deployment definitions:
65
66.. list-table::
67 :widths: 10 20 20
68 :header-rows: 1
69
70 * - Build Component
71 - Defines
72 - Reuse Scope
73 * - Application
74 - | Set of components that form the core application to be deployed.
75 - | All deployments of the application.
76 * - Infra
77 - | The set of adapters that realize the ports that the application depends on.
78 | An infrastructure definition may depend on:
79
80 * Environment specific components.
81 * Drivers that conform to a driver model.
82 * Platform specific drivers.
83 - | Any deployment that uses the same infrastructure to support the application.
84 | This will depend on how specific the infrastructure is. An infrastructure
85 | definition may allow for some level of configurability to enable deployment
86 | to impose a particular build configuration. Where an infrastructure includes
87 | adapters that use a well supported driver model (such as UEFI), the scope
88 | for reuse is large.
89 * - Env
90 - | The set of environment specific components that are common across all
91 | deployments of an application for a particular environment.
92 - | All deployments of the application into a specific environment. There is
93 | scope to improve reuse of environment specific components across multiple
94 | deployments.
95 * - Config
96 - | Build configuration variables together with a particular application, infra
97 | and env.
98 - | Depends on how specific the config is.
99
100Deployment Directory Structure
101------------------------------
102Using the block-storage deployment as an example, the deployment directory structure reflects
103the service deployment model as follows::
104
105 deployments
106 |- block-storage
107 |- block-storage.cmake - Common application build definition
108 |- env - Environment specific build definitions
109 |- infra - Alternative infrastructures
110 |- config - Configurations for block-storage deployments
111
112Configuration Definitions
113^^^^^^^^^^^^^^^^^^^^^^^^^
114To build a particular configuration of the block-storage service provider (in this case, one
115that uses flash storage on the N1SDP platform), use::
116
117 cd deployments/block-storage/config/n1sdp-flash
118 cmake -B build
119 cd build
120 make
121
122The CMakeLists.txt file for the n1sdp-flash deployment of the block-storage service provider
123includes:
124
125 - Set TS_PLATFORM to n1sdp platform name
126 - Set any build configuration parameter overrides
127 - Include ``${DEPLOYMENT_ROOT}/env/opteesp.cmake``
128 - Include ``${DEPLOYMENT_ROOT}/infra/edk2-flash.cmake``
129 - Include ``${DEPLOYMENT_ROOT}/block-storage.cmake``
130
131Each alternative deployment of the block-storage service provider is represented by a
132subdirectory under ``${DEPLOYMENT_ROOT}/config``. The number of directories under config is
133likely to grow to accommodate platform variability and different tradeoffs for how the infrastructure
134for an application will be realized.
135
136To support test and to provide a starting point for new config definitions, a default config should
137exist for each supported environment.
138
139Infrastructure Definitions
140^^^^^^^^^^^^^^^^^^^^^^^^^^
141An infrastructure defines a set of adapter components that realize the ports that the application
142depends on. For block-storage deployments, some possible infrastructures are:
143
144.. list-table::
145 :header-rows: 1
146 :widths: 10, 40
147
148 * - Infra Name
149 - Description
150 * - ref-ram
151 - Provides volatile storage using the reference partition configuration. Intended for test.
152 * - edk2-flash
153 - Provides persistent storage using a flash driver that conforms to the EDK2 driver model.
154 * - tfa-flash
155 - Provides persistent storage using a flash driver that conforms to the TF-A driver model.
156 * - rpmb
157 - Provides persistent storage using an RPMB partition, accessed via a Nwd agent.
158
159Platform Support
160----------------
161The Trusted Services project is not intended to be a home for platform specific code such as
162device drivers. Ideally, device drivers and other platform specific code should be reused
163from external upstream repos such as edk2-platforms. The ports and adapters pattern allows
164alternative driver models to be accommodated so different upstream projects with different
165driver models may be used without the need to modify driver code. Where driver reuse from
166an external project is not possible, the platform directory structure can accommodate driver
167components that reside within the TS project.
168
169The ability to accommodate third-party device drivers that conform to different driver models
170is important for enabling TS components to be used across different segments. The EDK2
171project for example can provide a rich source of drivers that conform to the UEFI model.
172UEFI is not however adopted in all product segments.
173
174All files related to supporting different platforms reside beneath the platform top-level
175directory.
176
177Platform Providers
178^^^^^^^^^^^^^^^^^^
179Within the TS project, a platform provider is responsible for adding and maintaining the
180glue that enables platform specific code to be used from a particular source. The platform
181code will either be:
182
183 - Fetched from an upstream repo (preferred)
184 - Added to the TS project.
185
186Each platform provider is represented by a subdirectory beneath ``platform/providers``. For
187Arm provided platforms, the structure will look something like this::
188
189 platform
190 |-- providers
191 |--arm
192 |-- corstone1000
193 |-- fvp
194 |-- fvp_base_aemva
195 |-- fvp_base_revc-2xaemv8a
196 |-- platform.cmake
197
198Under each platform leaf directory is a file called ``platform.cmake``. This file implements
199the common configuration and build interface that will be used during the deployment build
200process. How this interface is realized is entirely down to the platform provider. An
201implementation will do things like setting configuration variables for SoC, board and driver
202selection. Any additional files needed to support platform configuration and build may be
203included within the platform provider's sub-tree.
204
205For product developers who want to define and maintain their own private platforms, it should
206be possible to override the default ``platform/providers`` directory path to allow an
207alternative sub-tree to be used. A product developer is free to organize a private sub-tree
208in any way that suites their needs.
209
210Although the TS project structure doesn't mandate it, platform specific firmware is likely
211to live outside of the TS project. The ability to reuse existing drivers and driver frameworks
212is important for promoting adoption across hardware from different vendors. Board and silicon
213vendors may reuse existing CI and project infrastructure for platform components that they
214maintain.
215
216Platform support that depends on EDK2 platform components is represented by the edk2 platform
217provider. Files related to the EDK2 platform provider are organized as follows::
218
219 platform
220 |- providers
221 |- edk2
222 |- edk2-platforms.cmake - Fetches the upstream edk2-platforms repo
223 |- platform - Directory for platform definitions, organized by contributor
224 |- arm
225 |- n1sdp
226 |- platform.cmake
227
228Some special platforms are provided by the TS project itself. These are represented beneath
229the ts provider. Current TS platforms are:
230
231.. list-table::
232 :header-rows: 1
233 :widths: 10, 90
234
235 * - TS Platform
236 - Purpose
237 * - ``ts/vanilla``
238 - | A platform that never provides any drivers. The ``ts/vanilla`` platform should be used when an environment provides its own
239 | device framework and no additional drivers need to be provided by the platform. An attempt to build a deployment with
240 | platform dependencies on the vanilla platform will result in a build-time error. The vanilla platform is selected by
241 | default at build-time if no explicit platform has been specified.
242 * - ``ts/mock``
243 - | A platform that provides a complete set of drivers that may be selected when building any deployment. The platform uses
244 | mock drivers that don't offer functionality suitable for production builds. The mock platform is useful for CI build
245 | testing of deployments with platform dependencies. You should always expect a deployment with platform dependencies to
246 | build when ``TS_PLATFORM=ts/mock``.
247
248Diver Models
249^^^^^^^^^^^^
250Alternative driver models are represented by subdirectories beneath ``platform/driver_model``.
251Driver code imported from an external project, such as edk2-platforms, will also depend on
252interface and other header files related to the driver model. For drivers reused from
253edk2-platforms, the driver interface header files will define interface structures defined
254by the UEFI specification. The following example illustrates two driver models, one for
255UEFI drivers from the EDK2 project and another for bare-metal drivers that conform to TS
256defined interfaces::
257
258 platform
259 |- driver_model
260 |- edk2
261 |- baremetal
262
263Header files under the driver_model/edk2 directory will either explicitly provide definitions for
264the EDK2 driver model or include definitions from an external component. To maintain compatibility
265with driver code imported from edk2-platforms, sub-directories beneath platform/driver_model/edk2
266should conform to the EDK2 directory structure and naming conventions. The following illustrates
267how UEFI driver model files are organized::
268
269 platform
270 |- driver_model
271 |- edk2
272 |- interface
273 |- Protocol
274 | |- BlockIo.h
275 | |- DiskIo.h
276 | |- FirmwareVolumeBlock.h
277 |
278 |- Library
279 | |- IoLib.h
280 | |- DebugLib.h
281
282Drivers
283^^^^^^^
284The platforms/drivers directory provides a home for CMake files that enable driver code to be built
285as part of the the deployment build process. Source files will either have been fetched from an
286upstream repo or will live under the ``platform/drivers`` parent.
287
288--------------
289
290*Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.*
291
292SPDX-License-Identifier: BSD-3-Clause