xref: /aosp_15_r20/external/vboot_reference/tests/vb2_auxfw_sync_tests.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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