xref: /openbmc/hiomapd/test/flash_erase.c (revision 68a24c9e)
14f5d29cfSAndrew Jeffery // SPDX-License-Identifier: Apache-2.0
24f5d29cfSAndrew Jeffery // Copyright (C) 2018 IBM Corp.
34f5d29cfSAndrew Jeffery 
44f5d29cfSAndrew Jeffery #include <assert.h>
54f5d29cfSAndrew Jeffery #include <stdarg.h>
64f5d29cfSAndrew Jeffery #include <stdlib.h>
74f5d29cfSAndrew Jeffery #include <stdio.h>
826558dbbSAndrew Jeffery #include <string.h>
94f5d29cfSAndrew Jeffery #include <sys/ioctl.h>
104f5d29cfSAndrew Jeffery #include <unistd.h>
114f5d29cfSAndrew Jeffery 
124f5d29cfSAndrew Jeffery #include <linux/types.h>
134f5d29cfSAndrew Jeffery 
1426558dbbSAndrew Jeffery #include "common.h"
1526558dbbSAndrew Jeffery #include "mboxd.h"
16f1e547c7SEvan Lojewski #include "backend.h"
174f5d29cfSAndrew Jeffery 
184f5d29cfSAndrew Jeffery #include "test/tmpf.h"
194f5d29cfSAndrew Jeffery 
204f5d29cfSAndrew Jeffery static struct tmpf mtd;
214f5d29cfSAndrew Jeffery 
cleanup_mtd(void)224f5d29cfSAndrew Jeffery void cleanup_mtd(void)
234f5d29cfSAndrew Jeffery {
244f5d29cfSAndrew Jeffery 	tmpf_destroy(&mtd);
254f5d29cfSAndrew Jeffery }
264f5d29cfSAndrew Jeffery 
get_dev_mtd(void)274f5d29cfSAndrew Jeffery char *get_dev_mtd(void)
284f5d29cfSAndrew Jeffery {
294f5d29cfSAndrew Jeffery 	int rc;
304f5d29cfSAndrew Jeffery 
314f5d29cfSAndrew Jeffery 	rc = tmpf_init(&mtd, "flash-store.XXXXXX");
324f5d29cfSAndrew Jeffery 	if (rc < 0)
334f5d29cfSAndrew Jeffery 		return NULL;
344f5d29cfSAndrew Jeffery 
35f1e547c7SEvan Lojewski 	return mtd.path;
364f5d29cfSAndrew Jeffery }
374f5d29cfSAndrew Jeffery 
384f5d29cfSAndrew Jeffery struct erase_info_user *recorded;
394f5d29cfSAndrew Jeffery int n_ioctls;
404f5d29cfSAndrew Jeffery 
414f5d29cfSAndrew Jeffery #define MEM_SIZE 3
424f5d29cfSAndrew Jeffery #define ERASE_SIZE 1
434f5d29cfSAndrew Jeffery 
ioctl(int fd,unsigned long request,...)44*68a24c9eSPatrick Williams int ioctl(int fd __attribute__((unused)), unsigned long request, ...)
454f5d29cfSAndrew Jeffery {
464f5d29cfSAndrew Jeffery 	va_list ap;
474f5d29cfSAndrew Jeffery 	struct erase_info_user *provided, *alloced;
484f5d29cfSAndrew Jeffery 
494f5d29cfSAndrew Jeffery 	if (!(request == MEMERASE || request == MEMGETINFO)) {
504f5d29cfSAndrew Jeffery 		printf("Uh-oh: ioctl() called with request 0x%08lx\n", request);
514f5d29cfSAndrew Jeffery 		return -1;
524f5d29cfSAndrew Jeffery 	}
534f5d29cfSAndrew Jeffery 
544f5d29cfSAndrew Jeffery 	switch (request) {
554f5d29cfSAndrew Jeffery 	case MEMGETINFO:
564f5d29cfSAndrew Jeffery 	{
574f5d29cfSAndrew Jeffery 		struct mtd_info_user *info;
584f5d29cfSAndrew Jeffery 
594f5d29cfSAndrew Jeffery 		va_start(ap, request);
604f5d29cfSAndrew Jeffery 		info = va_arg(ap, struct mtd_info_user *);
614f5d29cfSAndrew Jeffery 		info->size = MEM_SIZE;
624f5d29cfSAndrew Jeffery 		info->erasesize = ERASE_SIZE;
634f5d29cfSAndrew Jeffery 		va_end(ap);
644f5d29cfSAndrew Jeffery 		break;
654f5d29cfSAndrew Jeffery 	}
664f5d29cfSAndrew Jeffery 	case MEMERASE:
674f5d29cfSAndrew Jeffery 		va_start(ap, request);
684f5d29cfSAndrew Jeffery 		provided = va_arg(ap, struct erase_info_user *);
694f5d29cfSAndrew Jeffery 
704f5d29cfSAndrew Jeffery 		n_ioctls++;
714f5d29cfSAndrew Jeffery 
724f5d29cfSAndrew Jeffery 		alloced = realloc(recorded, n_ioctls * sizeof(*recorded));
734f5d29cfSAndrew Jeffery 		if (!alloced)
744f5d29cfSAndrew Jeffery 			return -1;
754f5d29cfSAndrew Jeffery 		recorded = alloced;
764f5d29cfSAndrew Jeffery 
774f5d29cfSAndrew Jeffery 		memcpy(&recorded[n_ioctls - 1], provided, sizeof(*provided));
784f5d29cfSAndrew Jeffery 
794f5d29cfSAndrew Jeffery 		va_end(ap);
804f5d29cfSAndrew Jeffery 		break;
814f5d29cfSAndrew Jeffery 	default:
824f5d29cfSAndrew Jeffery 		break;
834f5d29cfSAndrew Jeffery 	}
844f5d29cfSAndrew Jeffery 
854f5d29cfSAndrew Jeffery 	return 0;
864f5d29cfSAndrew Jeffery }
874f5d29cfSAndrew Jeffery 
dump_ioctls(void)884f5d29cfSAndrew Jeffery void dump_ioctls(void)
894f5d29cfSAndrew Jeffery {
904f5d29cfSAndrew Jeffery 	int i;
914f5d29cfSAndrew Jeffery 
924f5d29cfSAndrew Jeffery 	printf("n_ioctls: %d\n", n_ioctls);
934f5d29cfSAndrew Jeffery 
944f5d29cfSAndrew Jeffery 	for (i = 0; i < n_ioctls; i++)
954f5d29cfSAndrew Jeffery 		printf("%d: start: %d, length %d\n",
964f5d29cfSAndrew Jeffery 				i, recorded[i].start, recorded[i].length);
974f5d29cfSAndrew Jeffery }
984f5d29cfSAndrew Jeffery 
main(void)994f5d29cfSAndrew Jeffery int main(void)
1004f5d29cfSAndrew Jeffery {
101f1e547c7SEvan Lojewski 	struct mbox_context context = {0};
102f1e547c7SEvan Lojewski 	struct backend *backend;
1034f5d29cfSAndrew Jeffery 	char data[MEM_SIZE];
1044f5d29cfSAndrew Jeffery 	int rc;
1054f5d29cfSAndrew Jeffery 
106f1e547c7SEvan Lojewski 	backend = &context.backend;
107f1e547c7SEvan Lojewski 
1084f5d29cfSAndrew Jeffery 	rc = atexit(cleanup_mtd);
1094f5d29cfSAndrew Jeffery 	if (rc)
1104f5d29cfSAndrew Jeffery 		return rc;
1114f5d29cfSAndrew Jeffery 
1124f5d29cfSAndrew Jeffery 	mbox_vlog = &mbox_log_console;
1134f5d29cfSAndrew Jeffery 
1144f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1154f5d29cfSAndrew Jeffery 	recorded = NULL;
1164f5d29cfSAndrew Jeffery 
117f1e547c7SEvan Lojewski 	assert(!backend_probe_mtd(backend, get_dev_mtd()));
1184f5d29cfSAndrew Jeffery 
1194f5d29cfSAndrew Jeffery 	/* Erase from an unknown state */
1200297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1214f5d29cfSAndrew Jeffery 
1224f5d29cfSAndrew Jeffery 	assert(rc == 0);
1234f5d29cfSAndrew Jeffery 	assert(n_ioctls == 1);
1244f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 0);
1254f5d29cfSAndrew Jeffery 	assert(recorded[0].length == sizeof(data));
1264f5d29cfSAndrew Jeffery 
1274f5d29cfSAndrew Jeffery 	free(recorded);
1284f5d29cfSAndrew Jeffery 	recorded = NULL;
1294f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1304f5d29cfSAndrew Jeffery 
1314f5d29cfSAndrew Jeffery 	/* Erase an erased flash */
1320297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1334f5d29cfSAndrew Jeffery 
1344f5d29cfSAndrew Jeffery 	assert(rc == 0);
1354f5d29cfSAndrew Jeffery 	assert(n_ioctls == 0);
1364f5d29cfSAndrew Jeffery 
1374f5d29cfSAndrew Jeffery 	memset(data, 0xaa, sizeof(data));
1384f5d29cfSAndrew Jeffery 
1394f5d29cfSAndrew Jeffery 	/* Erase written flash */
1400297e5b8SAndrew Jeffery 	rc = backend_write(backend, 0, data, sizeof(data));
1414f5d29cfSAndrew Jeffery 	assert(rc == 0);
1420297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1434f5d29cfSAndrew Jeffery 
1444f5d29cfSAndrew Jeffery 	assert(rc == 0);
1454f5d29cfSAndrew Jeffery 	assert(n_ioctls == 1);
1464f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 0);
1474f5d29cfSAndrew Jeffery 	assert(recorded[0].length == sizeof(data));
1484f5d29cfSAndrew Jeffery 
1494f5d29cfSAndrew Jeffery 	free(recorded);
1504f5d29cfSAndrew Jeffery 	recorded = NULL;
1514f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1524f5d29cfSAndrew Jeffery 
1534f5d29cfSAndrew Jeffery 	/* Erase the start of flash */
1540297e5b8SAndrew Jeffery 	rc = backend_write(backend, 0, data, sizeof(data) - 1);
1554f5d29cfSAndrew Jeffery 	assert(rc == 0);
1560297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1574f5d29cfSAndrew Jeffery 
1584f5d29cfSAndrew Jeffery 	assert(rc == 0);
1594f5d29cfSAndrew Jeffery 	assert(n_ioctls == 1);
1604f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 0);
1614f5d29cfSAndrew Jeffery 	assert(recorded[0].length == sizeof(data) - 1);
1624f5d29cfSAndrew Jeffery 
1634f5d29cfSAndrew Jeffery 	free(recorded);
1644f5d29cfSAndrew Jeffery 	recorded = NULL;
1654f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1664f5d29cfSAndrew Jeffery 
1674f5d29cfSAndrew Jeffery 	/* Erase the end of flash */
1680297e5b8SAndrew Jeffery 	rc = backend_write(backend, 1, data, sizeof(data) - 1);
1694f5d29cfSAndrew Jeffery 	assert(rc == 0);
1700297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1714f5d29cfSAndrew Jeffery 
1724f5d29cfSAndrew Jeffery 	assert(rc == 0);
1734f5d29cfSAndrew Jeffery 	assert(n_ioctls == 1);
1744f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 1);
1754f5d29cfSAndrew Jeffery 	assert(recorded[0].length == sizeof(data) - 1);
1764f5d29cfSAndrew Jeffery 
1774f5d29cfSAndrew Jeffery 	free(recorded);
1784f5d29cfSAndrew Jeffery 	recorded = NULL;
1794f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1804f5d29cfSAndrew Jeffery 
1814f5d29cfSAndrew Jeffery 	/* Erase each end of flash */
1820297e5b8SAndrew Jeffery 	rc = backend_write(backend, 0, data, 1);
1830297e5b8SAndrew Jeffery 	rc = backend_write(backend, 2, data, 1);
1844f5d29cfSAndrew Jeffery 	assert(rc == 0);
1850297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
1864f5d29cfSAndrew Jeffery 
1874f5d29cfSAndrew Jeffery 	assert(rc == 0);
1884f5d29cfSAndrew Jeffery 	assert(n_ioctls == 2);
1894f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 0);
1904f5d29cfSAndrew Jeffery 	assert(recorded[0].length == 1);
1914f5d29cfSAndrew Jeffery 	assert(recorded[1].start == 2);
1924f5d29cfSAndrew Jeffery 	assert(recorded[1].length == 1);
1934f5d29cfSAndrew Jeffery 
1944f5d29cfSAndrew Jeffery 	free(recorded);
1954f5d29cfSAndrew Jeffery 	recorded = NULL;
1964f5d29cfSAndrew Jeffery 	n_ioctls = 0;
1974f5d29cfSAndrew Jeffery 
1984f5d29cfSAndrew Jeffery 	/* Erase the middle of flash */
1990297e5b8SAndrew Jeffery 	rc = backend_write(backend, 1, data, 1);
2004f5d29cfSAndrew Jeffery 	assert(rc == 0);
2010297e5b8SAndrew Jeffery 	rc = backend_erase(backend, 0, sizeof(data));
2024f5d29cfSAndrew Jeffery 
2034f5d29cfSAndrew Jeffery 	assert(rc == 0);
2044f5d29cfSAndrew Jeffery 	assert(n_ioctls == 1);
2054f5d29cfSAndrew Jeffery 	assert(recorded[0].start == 1);
2064f5d29cfSAndrew Jeffery 	assert(recorded[0].length == 1);
2074f5d29cfSAndrew Jeffery 
2084f5d29cfSAndrew Jeffery 	free(recorded);
2094f5d29cfSAndrew Jeffery 	recorded = NULL;
2104f5d29cfSAndrew Jeffery 	n_ioctls = 0;
2114f5d29cfSAndrew Jeffery 
212f1e547c7SEvan Lojewski 	backend_free(backend);
2134f5d29cfSAndrew Jeffery 
2144f5d29cfSAndrew Jeffery 	return rc;
2154f5d29cfSAndrew Jeffery }
216