diff options
Diffstat (limited to 'roms/skiboot/external/opal-prd/test/test_pnor_ops.c')
-rw-r--r-- | roms/skiboot/external/opal-prd/test/test_pnor_ops.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/roms/skiboot/external/opal-prd/test/test_pnor_ops.c b/roms/skiboot/external/opal-prd/test/test_pnor_ops.c new file mode 100644 index 000000000..913f2ecf7 --- /dev/null +++ b/roms/skiboot/external/opal-prd/test/test_pnor_ops.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* Copyright 2015-2016 IBM Corp */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <mtd/mtd-user.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#undef ioctl +#define ioctl(d, req, arg) test_ioctl(d, req, arg) + +int test_ioctl(int fd, int req, void *arg) +{ + if (req == MEMERASE) { + uint8_t *buf; + struct erase_info_user *erase = arg; + + buf = malloc(erase->length); + memset(buf, 'E', erase->length); + + lseek(fd, erase->start, SEEK_SET); + write(fd, buf, erase->length); + + free(buf); + } + + return 0; +} + +#include "../pnor.c" + +bool compare_data(int fd, const uint8_t *check) +{ + uint8_t buf[16]; + int offset = 0; + int bytes_read; + int i; + + lseek(fd, 0, SEEK_SET); + + do { + bytes_read = read(fd, buf, sizeof(buf)); + i = 0; + while (i < bytes_read) + if (buf[i++] != check[offset++]) + return false; + } while (bytes_read == sizeof(buf)); + +out: + lseek(fd, 0, SEEK_SET); + + return true; +} + +void print_buf(uint8_t *buf, size_t len) +{ + int i; + + for (i = 0; i < len; i++) { + if (i % 16 == 0) + printf("\n%06x : ", i); + + printf("%c ", buf[i]); + } + printf("\n"); +} + +void print_file(int fd) +{ + uint8_t buf[16]; + int offset = 0; + int bytes_read; + int i; + + lseek(fd, 0, SEEK_SET); + + do { + bytes_read = read(fd, buf, sizeof(buf)); + if (bytes_read == 0) + break; + printf ("%06x : ", offset); + for (i = 0; i < bytes_read; ++i) + printf("%c ", buf[i]); + printf("\n"); + offset += bytes_read; + } while (bytes_read == sizeof(buf)); + + lseek(fd, 0, SEEK_SET); +} + +const uint8_t empty[32] = { + 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', + 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', + 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', + 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'}; + +const uint8_t test_one[32] = { + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'E', + 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'}; + +const uint8_t test_three[32] = { + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', + 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'E', + 'M', 'M', 'M', 'M', 'M', 'M', 'M', 'M'}; + +int main(int argc, char **argv) +{ + int fd, i, rc; + struct pnor pnor; + uint8_t data[24]; + char filename[24]; + + strcpy(filename, "/tmp/pnor-XXXXXX"); + + fd = mkstemp(filename); + if (fd < 0) { + perror("mkstemp"); + return EXIT_FAILURE; + } + /* So the file disappears when we exit */ + unlink(filename); + + /* E for empty */ + memset(data, 'E', sizeof(data)); + for (i = 0; i < 2; i++) + write(fd, data, 16); + + /* Adjust this if making the file smaller */ + pnor.size = 32; + + /* This is fake. Make it smaller than the size */ + pnor.erasesize = 4; + + printf("Write: "); + memset(data, 'A', sizeof(data)); + rc = mtd_write(&pnor, fd, data, 0, 23); + if (rc == 23 && compare_data(fd, test_one)) + printf("PASS\n"); + else + printf("FAIL: %d\n", rc); + + printf("Read: "); + memset(data, '0', sizeof(data)); + rc = mtd_read(&pnor, fd, data, 7, 24); + if (rc == 24 && !memcmp(data, &test_one[7], 24)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Write with offset: "); + memset(data, 'M', sizeof(data)); + rc = mtd_write(&pnor, fd, data, 24, 8); + if (rc == 8 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Write size past the end: "); + rc = mtd_write(&pnor, fd, data, 0, 64); + if (rc == -1 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL: %d\n", rc); + + printf("Write size past the end with offset: "); + rc = mtd_write(&pnor, fd, data, 24, 24); + if (rc == -1 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Write with offset past the end: "); + rc = mtd_write(&pnor, fd, data, 64, 12); + if (rc == -1 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Zero sized write: "); + rc = mtd_write(&pnor, fd, data, 0, 0); + if (rc == 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Zero sized write with offset: "); + rc = mtd_write(&pnor, fd, data, 12, 0); + if (rc == 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Read size past the end: "); + rc = mtd_read(&pnor, fd, data, 0, 64); + if (rc != 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + + printf("Read size past the end with offset: "); + rc = mtd_read(&pnor, fd, data, 24, 24); + if (rc != 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Read with offset past the end: "); + rc = mtd_read(&pnor, fd, data, 64, 12); + if (rc != 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Zero sized read: "); + rc = mtd_read(&pnor, fd, data, 0, 0); + if (rc == 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + printf("Zero sized read with offset: "); + rc = mtd_read(&pnor, fd, data, 12, 0); + if (rc == 0 && compare_data(fd, test_three)) + printf("PASS\n"); + else + printf("FAIL\n"); + + return 0; +} |