1 /* Copyright 2019 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Tests for auxfw synchronization.
6 */
7
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "2common.h"
13 #include "2misc.h"
14 #include "2nvstorage.h"
15 #include "2sysincludes.h"
16 #include "common/tests.h"
17 #include "host_common.h"
18 #include "vboot_struct.h"
19
20 /* Mock data */
21 static struct vb2_context *ctx;
22 static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]
23 __attribute__((aligned(VB2_WORKBUF_ALIGN)));
24 static struct vb2_shared_data *sd;
25 static struct vb2_gbb_header gbb;
26
27 static vb2_error_t auxfw_check_retval;
28 static vb2_error_t auxfw_update_retval;
29 static int auxfw_update_req;
30 static enum vb2_auxfw_update_severity auxfw_mock_severity;
31 static enum vb2_auxfw_update_severity auxfw_update_severity;
32 static int auxfw_mock_display_available;
33 static int auxfw_protected;
34 static vb2_error_t auxfw_done_retval;
35
36 /* Reset mock data (for use before each test) */
ResetMocks(void)37 static void ResetMocks(void)
38 {
39 TEST_SUCC(vb2api_init(workbuf, sizeof(workbuf), &ctx),
40 "vb2api_init failed");
41
42 ctx->flags = VB2_CONTEXT_EC_SYNC_SUPPORTED;
43 vb2_nv_init(ctx);
44
45 sd = vb2_get_sd(ctx);
46
47 memset(&gbb, 0, sizeof(gbb));
48
49 auxfw_check_retval = VB2_SUCCESS;
50 auxfw_update_retval = VB2_SUCCESS;
51 auxfw_mock_severity = VB2_AUXFW_NO_UPDATE;
52 auxfw_update_severity = VB2_AUXFW_NO_UPDATE;
53 auxfw_mock_display_available = 1;
54 auxfw_update_req = 0;
55 auxfw_protected = 0;
56 auxfw_done_retval = VB2_SUCCESS;
57 }
58
59 /* Mock functions */
vb2_get_gbb(struct vb2_context * c)60 struct vb2_gbb_header *vb2_get_gbb(struct vb2_context *c)
61 {
62 return &gbb;
63 }
64
vb2ex_auxfw_check(enum vb2_auxfw_update_severity * severity)65 vb2_error_t vb2ex_auxfw_check(enum vb2_auxfw_update_severity *severity)
66 {
67 *severity = auxfw_mock_severity;
68 auxfw_update_severity = auxfw_mock_severity;
69 return auxfw_check_retval;
70 }
71
vb2ex_auxfw_update(void)72 vb2_error_t vb2ex_auxfw_update(void)
73 {
74 if (auxfw_update_severity == VB2_AUXFW_SLOW_UPDATE)
75 if (!auxfw_mock_display_available)
76 return VB2_REQUEST_REBOOT;
77
78 if (auxfw_update_severity != VB2_AUXFW_NO_DEVICE &&
79 auxfw_update_severity != VB2_AUXFW_NO_UPDATE)
80 auxfw_update_req = 1;
81 return auxfw_update_retval;
82 }
83
vb2ex_auxfw_finalize(struct vb2_context * c)84 vb2_error_t vb2ex_auxfw_finalize(struct vb2_context *c)
85 {
86 auxfw_protected = auxfw_update_severity != VB2_AUXFW_NO_DEVICE;
87 return auxfw_done_retval;
88 }
89
test_auxsync(vb2_error_t retval,int recovery_reason,const char * desc)90 static void test_auxsync(vb2_error_t retval, int recovery_reason,
91 const char *desc)
92 {
93 TEST_EQ(vb2api_auxfw_sync(ctx), retval, desc);
94 TEST_EQ(vb2_nv_get(ctx, VB2_NV_RECOVERY_REQUEST),
95 recovery_reason, " recovery reason");
96 }
97
98 /* Tests */
99
VbSoftwareSyncTest(void)100 static void VbSoftwareSyncTest(void)
101 {
102 ResetMocks();
103 gbb.flags |= VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC;
104 auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
105 test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
106 "VB2_GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC"
107 " does not disable auxfw update request");
108 TEST_EQ(auxfw_update_req, 1, " auxfw update requested");
109 TEST_EQ(auxfw_protected, 0, " auxfw protected");
110
111 ResetMocks();
112 gbb.flags |= VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC;
113 auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
114 test_auxsync(VB2_SUCCESS, 0,
115 "VB2_GBB_FLAG_DISABLE_AUXFW_SOFTWARE_SYNC"
116 " disables auxfw update request");
117 TEST_EQ(auxfw_update_req, 0, " auxfw update disabled");
118 TEST_EQ(auxfw_protected, 1, " auxfw protected");
119
120 ResetMocks();
121 auxfw_mock_severity = VB2_AUXFW_NO_DEVICE;
122 test_auxsync(VB2_SUCCESS, 0,
123 "No auxfw update needed");
124 TEST_EQ(auxfw_update_req, 0, " no auxfw update requested");
125 TEST_EQ(auxfw_protected, 0, " no auxfw protected");
126
127 ResetMocks();
128 auxfw_mock_severity = VB2_AUXFW_NO_UPDATE;
129 test_auxsync(VB2_SUCCESS, 0,
130 "No auxfw update needed");
131 TEST_EQ(auxfw_update_req, 0, " no auxfw update requested");
132 TEST_EQ(auxfw_protected, 1, " auxfw protected");
133
134 ResetMocks();
135 auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
136 test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
137 "Fast auxfw update needed");
138 TEST_EQ(auxfw_update_req, 1, " auxfw update requested");
139 TEST_EQ(auxfw_protected, 0, " auxfw protected");
140
141 ResetMocks();
142 auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE;
143 auxfw_mock_display_available = 0;
144 test_auxsync(VB2_REQUEST_REBOOT, 0,
145 "Slow auxfw update needed - reboot for display");
146
147 ResetMocks();
148 vb2_nv_set(ctx, VB2_NV_DISPLAY_REQUEST, 1);
149 auxfw_mock_severity = VB2_AUXFW_SLOW_UPDATE;
150 test_auxsync(VB2_REQUEST_REBOOT_EC_TO_RO, 0,
151 "Slow auxfw update needed");
152 TEST_EQ(auxfw_update_req, 1, " auxfw update requested");
153 TEST_EQ(auxfw_protected, 0, " auxfw protected");
154 TEST_FALSE(vb2_nv_get(ctx, VB2_NV_DISPLAY_REQUEST),
155 " display request cleared");
156
157 ResetMocks();
158 auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
159 auxfw_check_retval = VB2_ERROR_UNKNOWN;
160 test_auxsync(VB2_ERROR_UNKNOWN, VB2_RECOVERY_AUXFW_UPDATE,
161 "Error checking auxfw");
162
163 ResetMocks();
164 auxfw_mock_severity = VB2_AUXFW_FAST_UPDATE;
165 auxfw_update_retval = VB2_ERROR_UNKNOWN;
166 test_auxsync(VB2_ERROR_UNKNOWN, VB2_RECOVERY_AUXFW_UPDATE,
167 "Error updating auxfw");
168 }
169
main(void)170 int main(void)
171 {
172 VbSoftwareSyncTest();
173
174 return gTestSuccess ? 0 : 255;
175 }
176