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