xref: /openbmc/hiomapd/test/flash_erase.c (revision 93c8edc9)
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 "flash.h"
17 
18 #include "test/tmpf.h"
19 
20 static struct tmpf mtd;
21 
22 void cleanup_mtd(void)
23 {
24 	tmpf_destroy(&mtd);
25 }
26 
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 strdup(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 
44 int ioctl(int fd, 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 
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 
99 int main(void)
100 {
101 	struct mbox_context context;
102 	char data[MEM_SIZE];
103 	int rc;
104 
105 	rc = atexit(cleanup_mtd);
106 	if (rc)
107 		return rc;
108 
109 	mbox_vlog = &mbox_log_console;
110 
111 	n_ioctls = 0;
112 	recorded = NULL;
113 
114 	flash_dev_init(&context);
115 
116 	/* Erase from an unknown state */
117 	rc = flash_erase(&context, 0, sizeof(data));
118 
119 	assert(rc == 0);
120 	assert(n_ioctls == 1);
121 	assert(recorded[0].start == 0);
122 	assert(recorded[0].length == sizeof(data));
123 
124 	free(recorded);
125 	recorded = NULL;
126 	n_ioctls = 0;
127 
128 	/* Erase an erased flash */
129 	rc = flash_erase(&context, 0, sizeof(data));
130 
131 	assert(rc == 0);
132 	assert(n_ioctls == 0);
133 
134 	memset(data, 0xaa, sizeof(data));
135 
136 	/* Erase written flash */
137 	rc = flash_write(&context, 0, data, sizeof(data));
138 	assert(rc == 0);
139 	rc = flash_erase(&context, 0, sizeof(data));
140 
141 	assert(rc == 0);
142 	assert(n_ioctls == 1);
143 	assert(recorded[0].start == 0);
144 	assert(recorded[0].length == sizeof(data));
145 
146 	free(recorded);
147 	recorded = NULL;
148 	n_ioctls = 0;
149 
150 	/* Erase the start of flash */
151 	rc = flash_write(&context, 0, data, sizeof(data) - 1);
152 	assert(rc == 0);
153 	rc = flash_erase(&context, 0, sizeof(data));
154 
155 	assert(rc == 0);
156 	assert(n_ioctls == 1);
157 	assert(recorded[0].start == 0);
158 	assert(recorded[0].length == sizeof(data) - 1);
159 
160 	free(recorded);
161 	recorded = NULL;
162 	n_ioctls = 0;
163 
164 	/* Erase the end of flash */
165 	rc = flash_write(&context, 1, data, sizeof(data) - 1);
166 	assert(rc == 0);
167 	rc = flash_erase(&context, 0, sizeof(data));
168 
169 	assert(rc == 0);
170 	assert(n_ioctls == 1);
171 	assert(recorded[0].start == 1);
172 	assert(recorded[0].length == sizeof(data) - 1);
173 
174 	free(recorded);
175 	recorded = NULL;
176 	n_ioctls = 0;
177 
178 	/* Erase each end of flash */
179 	rc = flash_write(&context, 0, data, 1);
180 	rc = flash_write(&context, 2, data, 1);
181 	assert(rc == 0);
182 	rc = flash_erase(&context, 0, sizeof(data));
183 
184 	assert(rc == 0);
185 	assert(n_ioctls == 2);
186 	assert(recorded[0].start == 0);
187 	assert(recorded[0].length == 1);
188 	assert(recorded[1].start == 2);
189 	assert(recorded[1].length == 1);
190 
191 	free(recorded);
192 	recorded = NULL;
193 	n_ioctls = 0;
194 
195 	/* Erase the middle of flash */
196 	rc = flash_write(&context, 1, data, 1);
197 	assert(rc == 0);
198 	rc = flash_erase(&context, 0, sizeof(data));
199 
200 	assert(rc == 0);
201 	assert(n_ioctls == 1);
202 	assert(recorded[0].start == 1);
203 	assert(recorded[0].length == 1);
204 
205 	free(recorded);
206 	recorded = NULL;
207 	n_ioctls = 0;
208 
209 	flash_dev_free(&context);
210 
211 	return rc;
212 }
213