1##########################
2Booting a Dual-Core System
3##########################
4
5:Author: Chris Brand
6:Organization: Cypress Semiconductor Corporation
7:Contact: chris.brand@cypress.com
8
9*******************
10System Architecture
11*******************
12There are many possibly ways to design a dual core system. Some important
13considerations from a boot perspective are:
14
15- Which core has access to which areas of Flash?
16
17    - It is possible that the secure core has no access to the Flash from which
18      the non-secure core will boot, in which case the non-secure core will
19      presumably have a separate root of trust and perform its own integrity
20      checks on boot.
21
22- How does the non-secure core behave on power-up? Is it held in reset,
23  does it jump to a set address, …?
24
25- What are the performance characteristics of the two core?
26
27    - There could be a great disparity in performance
28
29**********************
30TF-M Twin Core Booting
31**********************
32In an effort to make the problem manageable, as well as to provide a system
33with good performance, that is flexible enough to work for a variety of dual
34core systems, the following design decisions have been made:
35
36- TF-M will (for now) only support systems where the secure core has full
37  access to the Flash that the non-secure core will boot from
38
39    - This keeps the boot flow as close as possible to the single core design,
40      with the secure core responsible for maintaining the chain of trust for
41      the entire system, and for upgrade of the entire system
42
43- The secure code will make a platform-specific call immediately after setting
44  up hardware protection to (potentially) start the non-secure core running
45
46    - This is the earliest point at which it is safe to allow the non-secure
47      code to start running, so starting it here ensures system integrity while
48      also giving the non-secure code the maximum amount of time to perform its
49      initialization
50
51    - Note that this is after the bootloader has validated the non-secure image,
52      which is the other key part to maintain security
53
54    - This also means that only tfm_s and tfm_ns have to change, and not mcuboot
55
56- Both the secure and non-secure code will make platform-specific calls to
57  establish a synchronization point. This will be after both sides have done
58  any initialization that is required, including setting up inter-core
59  communications. On a single core system, this would be the point at which the
60  secure code jumps to the non-secure code, and at the very start of the
61  non-secure code.
62
63- After completing initialization on the secure core (at the point where on a
64  single core system, it would jump to the non-secure code), the main thread on
65  the secure core will be allowed to die
66
67    - The scheduler has been started at this point, and an idle thread exists.
68      Any additional work that is only required in the dual core case will be
69      interrupt-driven.
70
71    - All work related to the non-secure core will take place from a
72      ``ns_agent_mailbox`` partition, which will establish communication with
73      the non-secure core and then act on its behalf
74
75- Because both cores may be booting in parallel, executing different
76  initialization code, at different speeds, the design must be resilient if
77  either core attempts to communicate with the other before the latter is ready.
78  For example, the client (non-secure) side of the IPC mechanism must be able
79  to handle the situation where it has to wait for the server (secure) side to
80  finish setting up the IPC mechanism.
81
82    - This relates to the synchronization calls mentioned above. It means that
83      those calls cannot utilise the IPC mechanism, but must instead use some
84      platform-specific mechanism to establish this synchronization. This could
85      be as simple as setting aside a small area of shared memory and having
86      both sides set a “ready” flag, but may well also involve the use of
87      interrupts.
88
89    - This also means that the synchronization call must take place after the
90      IPC mechanism has been set up but before any attempt (by either side) to
91      use it.
92
93*************
94API Additions
95*************
96Three new HAL functions are required:
97
98.. code-block:: c
99
100    void tfm_hal_boot_ns_cpu(uintptr_t start_addr);
101
102- Called on the secure core from ``ns_agent_mailbox`` partition when it first
103  runs (after protections have been configured).
104
105- Performs the necessary actions to start the non-secure core running the code
106  at the specified address.
107
108.. code-block:: c
109
110    void tfm_hal_wait_for_ns_cpu_ready(void);
111
112- Called on the secure core from ``ns_agent_mailbox`` partition after making the
113  above call.
114
115- Flags that the secure core has completed its initialization, including setting
116  up the IPC mechanism.
117
118- Waits, if necessary, for the non-secure core to flag that it has completed its
119  initialisation
120
121.. code-block:: c
122
123    void tfm_ns_wait_for_s_cpu_ready(void);
124
125- Called on the non-secure core from ``main()`` after the dual-core-specific
126  initialization (on a single core system, this would be the start of the
127  non-secure code), before the first use of the IPC mechanism.
128
129- Flags that the non-secure side has completed its initialization.
130
131- Waits, if necessary, for the secure core to flag that it has completed its
132  initialization.
133
134For all three, an empty implementation will be provided with a weak symbol so
135that platforms only have to provide the new functions if they are required.
136
137---------------
138
139Copyright (c) 2019-2022 Cypress Semiconductor Corporation. All rights reserved.
140Copyright (c) 2021, Arm Limited. All rights reserved.
141
142