summaryrefslogtreecommitdiff
path: root/zephyr/test/jump_tags/src/jump_tags.c
blob: 5811f11648f6c0593a673f8eb25fc01c1faa195e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <setjmp.h>

#include "ec_commands.h"
#include "hooks.h"
#include "host_command.h"
#include "sysjump.h"
#include "system_fake.h"
#include "system.h"

#define TEST_BASIC_JUMP_TAG 0x9901
#define TEST_MISSING_JUMP_TAG 0x9902
#define TEST_MAX_JUMP_TAG 0x9903
#define TEST_TOO_BIG_JUMP_TAG 0x9904

#define TEST_JUMP_TAG_VERSION 1

#define SOME_STR_VAL "JumpTagTest"

void (*add_tag_func)(void);

struct test_basic_jump_data_struct {
	char some_str[32];
};

struct test_max_jump_data_struct {
	char some_str[JUMP_TAG_MAX_SIZE];
};

struct test_too_big_jump_data_struct {
	char some_str[JUMP_TAG_MAX_SIZE + 1];
};

static void system_before(void *data)
{
	add_tag_func = NULL;
	system_common_pre_init();
	system_set_shrspi_image_copy(EC_IMAGE_RO);
}

static void do_fake_sysjump(void)
{
	jmp_buf env;
	enum ec_image target_image = system_get_image_copy() == EC_IMAGE_RO ?
					     EC_IMAGE_RW :
					     EC_IMAGE_RO;

	if (!setjmp(env)) {
		system_fake_setenv(&env);
		system_run_image_copy(target_image);
		zassert_unreachable();
	}

	system_set_shrspi_image_copy(target_image);
	zassert_equal(system_get_image_copy(), target_image);
}

static void add_max_jump_tag(void)
{
	struct test_max_jump_data_struct max_tag = {
		.some_str = SOME_STR_VAL,
	};
	zassert_ok(system_add_jump_tag(TEST_MAX_JUMP_TAG, TEST_JUMP_TAG_VERSION,
				       sizeof(max_tag), &max_tag));
}

static void add_too_big_jump_tag(void)
{
	struct test_too_big_jump_data_struct too_big_tag = {
		.some_str = SOME_STR_VAL,
	};
	zassert_equal(system_add_jump_tag(TEST_TOO_BIG_JUMP_TAG,
					  TEST_JUMP_TAG_VERSION,
					  sizeof(too_big_tag), &too_big_tag),
		      EC_ERROR_INVAL);
}

static void add_too_many_jump_tags(void)
{
	int rv;
	struct test_max_jump_data_struct max_tag = {
		.some_str = SOME_STR_VAL,
	};
	/* Ensure at least one tag can be added, but not 10 */
	for (int i = 0; i < 10; i++) {
		rv = system_add_jump_tag(TEST_MAX_JUMP_TAG,
					 TEST_JUMP_TAG_VERSION, sizeof(max_tag),
					 &max_tag);
		if (rv != 0) {
			zassert_equal(rv, EC_ERROR_INVAL);
			zassert_true(i > 0);
			return;
		}
	}
	zassert_unreachable(
		"Adding too many jump tags failed to result in an error");
}

static void add_basic_jump_tag(void)
{
	struct test_basic_jump_data_struct basic_tag = {
		.some_str = SOME_STR_VAL,
	};
	zassert_ok(system_add_jump_tag(TEST_BASIC_JUMP_TAG,
				       TEST_JUMP_TAG_VERSION, sizeof(basic_tag),
				       &basic_tag));
}

static void test_sysjump_hook(void)
{
	if (add_tag_func)
		add_tag_func();
}
DECLARE_HOOK(HOOK_SYSJUMP, test_sysjump_hook, HOOK_PRIO_DEFAULT);

static void check_for_jump_tag(int jump_tag, int expected_size)
{
	int version;
	int size;
	const unsigned char *data;

	data = system_get_jump_tag(jump_tag, &version, &size);
	zassert_equal(size, expected_size);
	zassert_equal(version, TEST_JUMP_TAG_VERSION);
	zassert_equal(strcmp(data, SOME_STR_VAL), 0);
}

ZTEST(jump_tags, test_get_missing_jump_tag)
{
	int version;
	int size;
	struct test_jump_data_struct *data;

	data = (struct test_jump_data_struct *)system_get_jump_tag(
		TEST_MISSING_JUMP_TAG, &version, &size);
	zassert_equal(data, NULL);
}

ZTEST(jump_tags, test_add_max_jump_tag)
{
	add_tag_func = add_max_jump_tag;
	do_fake_sysjump();
	check_for_jump_tag(TEST_MAX_JUMP_TAG,
			   sizeof(struct test_max_jump_data_struct));
}

ZTEST(jump_tags, test_too_big_jump_tag)
{
	add_tag_func = add_too_big_jump_tag;
	do_fake_sysjump();
}

ZTEST(jump_tags, test_too_many_jump_tags)
{
	add_tag_func = add_too_many_jump_tags;
	do_fake_sysjump();
	check_for_jump_tag(TEST_MAX_JUMP_TAG,
			   sizeof(struct test_max_jump_data_struct));
}

ZTEST(jump_tags, test_add_basic_jump_tag)
{
	add_tag_func = add_basic_jump_tag;
	do_fake_sysjump();
	check_for_jump_tag(TEST_BASIC_JUMP_TAG,
			   sizeof(struct test_basic_jump_data_struct));
}

ZTEST_SUITE(jump_tags, NULL, NULL, system_before, NULL, NULL);