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