summaryrefslogtreecommitdiff
path: root/test/flash_write_protect.c
blob: 138aab24ff339092b54504b3d76e20350f8b45e2 (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
/* Copyright 2020 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "flash.h"
#include "gpio.h"
#include "string.h"
#include "system.h"
#include "task.h"
#include "test_util.h"
#include "write_protect.h"

test_static int check_image_and_hardware_write_protect(void)
{
	bool wp;

	if (system_get_image_copy() != EC_IMAGE_RO) {
		ccprintf("This test is only works when running RO\n");
		return EC_ERROR_UNKNOWN;
	}

	wp = write_protect_is_asserted();

	if (!wp) {
		ccprintf("Hardware write protect (GPIO_WP) must be enabled\n");
		return EC_ERROR_UNKNOWN;
	}

	return EC_SUCCESS;
}

test_static int test_flash_write_protect_enable(void)
{
	int rv;

	TEST_EQ(check_image_and_hardware_write_protect(), EC_SUCCESS, "%d");

	/* Equivalent of ectool --name=cros_fp flashprotect enable */
	rv = crec_flash_set_protect(EC_FLASH_PROTECT_RO_AT_BOOT,
				    EC_FLASH_PROTECT_RO_AT_BOOT);

	return rv;
}

test_static int test_flash_write_protect_disable(void)
{
	int rv;

	TEST_EQ(check_image_and_hardware_write_protect(), EC_SUCCESS, "%d");

	/* Equivalent of ectool --name=cros_fp flashprotect disable */
	rv = crec_flash_set_protect(EC_FLASH_PROTECT_RO_AT_BOOT, 0);
	TEST_NE(rv, EC_SUCCESS, "%d");

	return EC_SUCCESS;
}

test_static void run_test_step1(void)
{
	ccprintf("Step 1: Flash write protect test\n");
	RUN_TEST(test_flash_write_protect_enable);

	if (test_get_error_count())
		test_reboot_to_next_step(TEST_STATE_FAILED);
	else
		test_reboot_to_next_step(TEST_STATE_STEP_2);
}

test_static void run_test_step2(void)
{
	ccprintf("Step 2: Flash write protect test\n");
	RUN_TEST(test_flash_write_protect_disable);

	if (test_get_error_count())
		test_reboot_to_next_step(TEST_STATE_FAILED);
	else if (IS_ENABLED(CONFIG_EEPROM_CBI_WP))
		test_reboot_to_next_step(TEST_STATE_STEP_3);
	else
		test_reboot_to_next_step(TEST_STATE_PASSED);
}

#ifdef CONFIG_EEPROM_CBI_WP
test_static int test_cbi_wb_asserted_immediately(void)
{
	int rv;

	TEST_EQ(check_image_and_hardware_write_protect(), EC_SUCCESS, "%d");

	/* Ensure that EC_CBI_WP is not asserted. */
	TEST_EQ(gpio_get_level(GPIO_EC_CBI_WP), 0, "%d");

	/* Equivalent of ectool --name=cros_fp flashprotect disable */
	rv = crec_flash_set_protect(EC_FLASH_PROTECT_RO_NOW, 0);
	TEST_EQ(rv, EC_SUCCESS, "%d");

	/* Now make sure EC_CBI_WP is asserted immediately. */
	TEST_EQ(gpio_get_level(GPIO_EC_CBI_WP), 1, "%d");

	return EC_SUCCESS;
}

test_static void run_test_step3(void)
{
	ccprintf("Step 3: Flash write protect test\n");
	RUN_TEST(test_cbi_wb_asserted_immediately);

	if (test_get_error_count())
		test_reboot_to_next_step(TEST_STATE_FAILED);
	else
		test_reboot_to_next_step(TEST_STATE_PASSED);
}
#endif /* CONFIG_EEPROM_CBI_WP */

void test_run_step(uint32_t state)
{
	if (state & TEST_STATE_MASK(TEST_STATE_STEP_1))
		run_test_step1();
	else if (state & TEST_STATE_MASK(TEST_STATE_STEP_2))
		run_test_step2();
#ifdef CONFIG_EEPROM_CBI_WP
	else if (state & TEST_STATE_MASK(TEST_STATE_STEP_3))
		run_test_step3();
#endif /* CONFIG_EEPROM_CBI_WP */
}

int task_test(void *unused)
{
	test_run_multistep();
	return EC_SUCCESS;
}

void run_test(int argc, const char **argv)
{
	msleep(30); /* Wait for TASK_ID_TEST to initialize */
	task_wake(TASK_ID_TEST);
}