Software APIs
boot_svc_msg.h
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_SVC_BOOT_SVC_MSG_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_SVC_BOOT_SVC_MSG_H_
7
9#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h"
10#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_enter_rescue.h"
11#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_header.h"
12#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_min_bl0_sec_ver.h"
13#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_next_boot_bl0_slot.h"
14#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_ownership_activate.h"
15#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_ownership_history.h"
16#include "sw/device/silicon_creator/lib/boot_svc/boot_svc_ownership_unlock.h"
17
18#ifdef __cplusplus
19extern "C" {
20#endif // __cplusplus
21
22/**
23 * Table of boot services request and response types.
24 *
25 * Columns: Data type, `boot_svc_msg_t` union field name.
26 * We use an X macro to generate the assertion that checks
27 * the value of `CHIP_BOOT_SVC_MSG_SIZE_MAX`.
28 */
29// clang-format off
30#define BOOT_SVC_MSGS_DEFINE(X) \
31 /**
32 * Empty boot services message.
33 */ \
34 X(boot_svc_empty_t, empty) \
35 /**
36 * Enter rescue mode.
37 */ \
38 X(boot_svc_enter_rescue_req_t, enter_rescue_req) \
39 X(boot_svc_enter_rescue_res_t, enter_rescue_res) \
40 /**
41 * Next Boot BL0 Slot request and response.
42 */ \
43 X(boot_svc_next_boot_bl0_slot_req_t, next_boot_bl0_slot_req) \
44 X(boot_svc_next_boot_bl0_slot_res_t, next_boot_bl0_slot_res) \
45 /**
46 * Set Minimum Security Version request and response.
47 */ \
48 X(boot_svc_min_bl0_sec_ver_req_t, min_bl0_sec_ver_req) \
49 X(boot_svc_min_bl0_sec_ver_res_t, min_bl0_sec_ver_res) \
50 /**
51 * Ownership Activate
52 */ \
53 X(boot_svc_ownership_activate_req_t, ownership_activate_req) \
54 X(boot_svc_ownership_activate_res_t, ownership_activate_res) \
55 /**
56 * Ownership History
57 */ \
58 X(boot_svc_ownership_history_req_t, ownership_history_req) \
59 X(boot_svc_ownership_history_res_t, ownership_history_res) \
60 /**
61 * Ownership Unlock
62 */ \
63 X(boot_svc_ownership_unlock_req_t, ownership_unlock_req) \
64 X(boot_svc_ownership_unlock_res_t, ownership_unlock_res)
65// clang-format on
66
67/**
68 * Helper macro for declaring fields for boot services messages
69 *
70 * @param type_ Data type.
71 * @param field_name_ `boot_svc_msg_t` union field name.
72 */
73#define BOOT_SVC_MSG_FIELD(type_, field_name_) type_ field_name_;
74
75/**
76 * A Boot Services message.
77 *
78 * This is defined as a union where the common initial sequence is a
79 * `boot_svc_header_t`. This makes it possible to store and read different types
80 * of messages to the same location without invoking undefined behavior.
81 */
82typedef union boot_svc_msg {
83 /**
84 * Common initial sequence.
85 */
86 boot_svc_header_t header;
87 /**
88 * Boot services request and response messages.
89 */
90 BOOT_SVC_MSGS_DEFINE(BOOT_SVC_MSG_FIELD);
91} boot_svc_msg_t;
92
93OT_ASSERT_SIZE(boot_svc_msg_t, 256);
94
95/**
96 * Helper macro for generating the equalities for checking that the value of
97 * `CHIP_BOOT_SVC_MSG_SIZE_MAX` is equal to the size of at least one of the boot
98 * services messages.
99 *
100 * Note that the macro expands to an incomplete expression that must be
101 * terminated with `false`.
102 *
103 * @param type_ Data type.
104 * @param field_name_ `boot_svc_msg_t` union field name.
105 */
106#define BOOT_SVC_SIZE_EQ_(type_, field_name_) \
107 sizeof(type_) == CHIP_BOOT_SVC_MSG_SIZE_MAX ||
108
109static_assert(BOOT_SVC_MSGS_DEFINE(BOOT_SVC_SIZE_EQ_) false,
110 "CHIP_BOOT_SVC_MSG_SIZE_MAX must equal to the size of at least "
111 "one of the boot services messages");
112
113#undef BOOT_SVC_SIZE_EQ_
114
115/**
116 * Helper macro for generating the inequalities for checking that the value of
117 * `CHIP_BOOT_SVC_MSG_SIZE_MAX` is greater than or equal to the sizes of all
118 * boot services messages.
119 *
120 * Note that the macro expands to an incomplete expression that must be
121 * terminated with `true`.
122 *
123 * @param type_ Data type.
124 * @param field_name_ `boot_svc_msg_t` union field name.
125 */
126#define BOOT_SVC_SIZE_LE_(type_, field_name_) \
127 sizeof(type_) <= CHIP_BOOT_SVC_MSG_SIZE_MAX &&
128
129static_assert(BOOT_SVC_MSGS_DEFINE(BOOT_SVC_SIZE_LE_) true,
130 "CHIP_BOOT_SVC_MSG_SIZE_MAX must be greater than or equal to the "
131 "sizes of all of the boot services messages");
132
133#undef BOOT_SVC_SIZE_LE_
134
135#ifdef __cplusplus
136} // extern "C"
137#endif // __cplusplus
138
139#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_BOOT_SVC_BOOT_SVC_MSG_H_