xref: /openbmc/phosphor-mboxd/test/erase_flash.c (revision acdbdd14)
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2018 IBM Corp.
3 
4 #include <assert.h>
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <sys/ioctl.h>
9 #include <unistd.h>
10 
11 #include <linux/types.h>
12 
13 #include "mbox.h"
14 #include "mboxd_flash.h"
15 
16 #include "test/tmpf.h"
17 
18 static struct tmpf mtd;
19 
cleanup_mtd(void)20 void cleanup_mtd(void)
21 {
22 	tmpf_destroy(&mtd);
23 }
24 
get_dev_mtd(void)25 char *get_dev_mtd(void)
26 {
27 	int rc;
28 
29 	rc = tmpf_init(&mtd, "flash-store.XXXXXX");
30 	if (rc < 0)
31 		return NULL;
32 
33 	return strdup(mtd.path);
34 }
35 
36 struct erase_info_user *recorded;
37 int n_ioctls;
38 
39 #define MEM_SIZE 3
40 #define ERASE_SIZE 1
41 
ioctl(int fd,unsigned long request,...)42 int ioctl(int fd, unsigned long request, ...)
43 {
44 	va_list ap;
45 	struct erase_info_user *provided, *alloced;
46 
47 	if (!(request == MEMERASE || request == MEMGETINFO)) {
48 		printf("Uh-oh: ioctl() called with request 0x%08lx\n", request);
49 		return -1;
50 	}
51 
52 	switch (request) {
53 	case MEMGETINFO:
54 	{
55 		struct mtd_info_user *info;
56 
57 		va_start(ap, request);
58 		info = va_arg(ap, struct mtd_info_user *);
59 		info->size = MEM_SIZE;
60 		info->erasesize = ERASE_SIZE;
61 		va_end(ap);
62 		break;
63 	}
64 	case MEMERASE:
65 		va_start(ap, request);
66 		provided = va_arg(ap, struct erase_info_user *);
67 
68 		n_ioctls++;
69 
70 		alloced = realloc(recorded, n_ioctls * sizeof(*recorded));
71 		if (!alloced)
72 			return -1;
73 		recorded = alloced;
74 
75 		memcpy(&recorded[n_ioctls - 1], provided, sizeof(*provided));
76 
77 		va_end(ap);
78 		break;
79 	default:
80 		break;
81 	}
82 
83 	return 0;
84 }
85 
dump_ioctls(void)86 void dump_ioctls(void)
87 {
88 	int i;
89 
90 	printf("n_ioctls: %d\n", n_ioctls);
91 
92 	for (i = 0; i < n_ioctls; i++)
93 		printf("%d: start: %d, length %d\n",
94 				i, recorded[i].start, recorded[i].length);
95 }
96 
main(void)97 int main(void)
98 {
99 	struct mbox_context context;
100 	char data[MEM_SIZE];
101 	int rc;
102 
103 	rc = atexit(cleanup_mtd);
104 	if (rc)
105 		return rc;
106 
107 	mbox_vlog = &mbox_log_console;
108 
109 	n_ioctls = 0;
110 	recorded = NULL;
111 
112 	init_flash_dev(&context);
113 
114 	/* Erase from an unknown state */
115 	rc = erase_flash(&context, 0, sizeof(data));
116 
117 	assert(rc == 0);
118 	assert(n_ioctls == 1);
119 	assert(recorded[0].start == 0);
120 	assert(recorded[0].length == sizeof(data));
121 
122 	free(recorded);
123 	recorded = NULL;
124 	n_ioctls = 0;
125 
126 	/* Erase an erased flash */
127 	rc = erase_flash(&context, 0, sizeof(data));
128 
129 	assert(rc == 0);
130 	assert(n_ioctls == 0);
131 
132 	memset(data, 0xaa, sizeof(data));
133 
134 	/* Erase written flash */
135 	rc = write_flash(&context, 0, data, sizeof(data));
136 	assert(rc == 0);
137 	rc = erase_flash(&context, 0, sizeof(data));
138 
139 	assert(rc == 0);
140 	assert(n_ioctls == 1);
141 	assert(recorded[0].start == 0);
142 	assert(recorded[0].length == sizeof(data));
143 
144 	free(recorded);
145 	recorded = NULL;
146 	n_ioctls = 0;
147 
148 	/* Erase the start of flash */
149 	rc = write_flash(&context, 0, data, sizeof(data) - 1);
150 	assert(rc == 0);
151 	rc = erase_flash(&context, 0, sizeof(data));
152 
153 	assert(rc == 0);
154 	assert(n_ioctls == 1);
155 	assert(recorded[0].start == 0);
156 	assert(recorded[0].length == sizeof(data) - 1);
157 
158 	free(recorded);
159 	recorded = NULL;
160 	n_ioctls = 0;
161 
162 	/* Erase the end of flash */
163 	rc = write_flash(&context, 1, data, sizeof(data) - 1);
164 	assert(rc == 0);
165 	rc = erase_flash(&context, 0, sizeof(data));
166 
167 	assert(rc == 0);
168 	assert(n_ioctls == 1);
169 	assert(recorded[0].start == 1);
170 	assert(recorded[0].length == sizeof(data) - 1);
171 
172 	free(recorded);
173 	recorded = NULL;
174 	n_ioctls = 0;
175 
176 	/* Erase each end of flash */
177 	rc = write_flash(&context, 0, data, 1);
178 	rc = write_flash(&context, 2, data, 1);
179 	assert(rc == 0);
180 	rc = erase_flash(&context, 0, sizeof(data));
181 
182 	assert(rc == 0);
183 	assert(n_ioctls == 2);
184 	assert(recorded[0].start == 0);
185 	assert(recorded[0].length == 1);
186 	assert(recorded[1].start == 2);
187 	assert(recorded[1].length == 1);
188 
189 	free(recorded);
190 	recorded = NULL;
191 	n_ioctls = 0;
192 
193 	/* Erase the middle of flash */
194 	rc = write_flash(&context, 1, data, 1);
195 	assert(rc == 0);
196 	rc = erase_flash(&context, 0, sizeof(data));
197 
198 	assert(rc == 0);
199 	assert(n_ioctls == 1);
200 	assert(recorded[0].start == 1);
201 	assert(recorded[0].length == 1);
202 
203 	free(recorded);
204 	recorded = NULL;
205 	n_ioctls = 0;
206 
207 	free_flash_dev(&context);
208 
209 	return rc;
210 }
211