From ba010851fafea3da0d0655b103158f0a9efe6406 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Mon, 19 Dec 2022 21:46:52 +0000 Subject: [PATCH] Remove lib/x1000-installer Carrying this library is somewhat of a maintenance burden because some Rockbox APIs are mocked or duplicated in the test suite and thus need to be fixed up when refactoring. It's also unused & incomplete, so there's no good reason to keep it in tree any more. Change-Id: If39c62744b4edc0d81b1b6608ee5df69430e6581 --- lib/x1000-installer/.gitignore | 5 - lib/x1000-installer/Makefile | 82 ----- lib/x1000-installer/SOURCES | 6 - lib/x1000-installer/include/xf_error.h | 43 --- lib/x1000-installer/include/xf_flashmap.h | 91 ----- lib/x1000-installer/include/xf_nandio.h | 130 ------- lib/x1000-installer/include/xf_package.h | 65 ---- lib/x1000-installer/include/xf_stream.h | 64 ---- lib/x1000-installer/include/xf_update.h | 53 --- lib/x1000-installer/src/xf_error.c | 42 --- lib/x1000-installer/src/xf_flashmap.c | 327 ------------------ lib/x1000-installer/src/xf_nandio.c | 292 ---------------- lib/x1000-installer/src/xf_package.c | 261 -------------- lib/x1000-installer/src/xf_stream.c | 211 ----------- lib/x1000-installer/src/xf_update.c | 149 -------- .../test/data/lines_shuffled.txt | 108 ------ .../test/data/lines_sorted.txt | 36 -- lib/x1000-installer/test/main.c | 86 ----- lib/x1000-installer/test/test.h | 39 --- lib/x1000-installer/test/test_flashmap.c | 140 -------- lib/x1000-installer/test/test_stream.c | 108 ------ lib/x1000-installer/test_lib/core_alloc.c | 72 ---- lib/x1000-installer/test_lib/core_alloc.h | 43 --- lib/x1000-installer/test_lib/fakenand.c | 270 --------------- lib/x1000-installer/test_lib/file.c | 11 - lib/x1000-installer/test_lib/file.h | 18 - lib/x1000-installer/test_lib/md5.c | 245 ------------- lib/x1000-installer/test_lib/md5.h | 18 - lib/x1000-installer/test_lib/nand-x1000.h | 112 ------ lib/x1000-installer/test_lib/pathfuncs.c | 130 ------- lib/x1000-installer/test_lib/pathfuncs.h | 39 --- lib/x1000-installer/test_lib/strlcpy.c | 50 --- lib/x1000-installer/test_lib/strlcpy.h | 4 - lib/x1000-installer/test_lib/system.h | 10 - lib/x1000-installer/x1000-installer.make | 21 -- 35 files changed, 3381 deletions(-) delete mode 100644 lib/x1000-installer/.gitignore delete mode 100644 lib/x1000-installer/Makefile delete mode 100644 lib/x1000-installer/SOURCES delete mode 100644 lib/x1000-installer/include/xf_error.h delete mode 100644 lib/x1000-installer/include/xf_flashmap.h delete mode 100644 lib/x1000-installer/include/xf_nandio.h delete mode 100644 lib/x1000-installer/include/xf_package.h delete mode 100644 lib/x1000-installer/include/xf_stream.h delete mode 100644 lib/x1000-installer/include/xf_update.h delete mode 100644 lib/x1000-installer/src/xf_error.c delete mode 100644 lib/x1000-installer/src/xf_flashmap.c delete mode 100644 lib/x1000-installer/src/xf_nandio.c delete mode 100644 lib/x1000-installer/src/xf_package.c delete mode 100644 lib/x1000-installer/src/xf_stream.c delete mode 100644 lib/x1000-installer/src/xf_update.c delete mode 100644 lib/x1000-installer/test/data/lines_shuffled.txt delete mode 100644 lib/x1000-installer/test/data/lines_sorted.txt delete mode 100644 lib/x1000-installer/test/main.c delete mode 100644 lib/x1000-installer/test/test.h delete mode 100644 lib/x1000-installer/test/test_flashmap.c delete mode 100644 lib/x1000-installer/test/test_stream.c delete mode 100644 lib/x1000-installer/test_lib/core_alloc.c delete mode 100644 lib/x1000-installer/test_lib/core_alloc.h delete mode 100644 lib/x1000-installer/test_lib/fakenand.c delete mode 100644 lib/x1000-installer/test_lib/file.c delete mode 100644 lib/x1000-installer/test_lib/file.h delete mode 100644 lib/x1000-installer/test_lib/md5.c delete mode 100644 lib/x1000-installer/test_lib/md5.h delete mode 100644 lib/x1000-installer/test_lib/nand-x1000.h delete mode 100644 lib/x1000-installer/test_lib/pathfuncs.c delete mode 100644 lib/x1000-installer/test_lib/pathfuncs.h delete mode 100644 lib/x1000-installer/test_lib/strlcpy.c delete mode 100644 lib/x1000-installer/test_lib/strlcpy.h delete mode 100644 lib/x1000-installer/test_lib/system.h delete mode 100644 lib/x1000-installer/x1000-installer.make diff --git a/lib/x1000-installer/.gitignore b/lib/x1000-installer/.gitignore deleted file mode 100644 index e7ad25b29f..0000000000 --- a/lib/x1000-installer/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -xf_test -fakeNAND.bin -fakeNAND_meta.bin -*.profraw -*.profdata diff --git a/lib/x1000-installer/Makefile b/lib/x1000-installer/Makefile deleted file mode 100644 index 54c590dce4..0000000000 --- a/lib/x1000-installer/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -OBJ = src/xf_error.o \ - src/xf_flashmap.o \ - src/xf_nandio.o \ - src/xf_package.o \ - src/xf_stream.o \ - src/xf_update.o -LIB = libx1000-installer.a - -TOBJ = test_lib/core_alloc.o \ - test_lib/fakenand.o \ - test_lib/file.o \ - test_lib/pathfuncs.o \ - test_lib/md5.o \ - test_lib/strlcpy.o \ - test/main.o \ - test/test_flashmap.o \ - test/test_stream.o -TBIN = xf_test - -# dependency needs to be built manually -MTARINC = -I../microtar/src -MTARLIB = ../microtar/libmicrotar.a - -CPPFLAGS = -Iinclude -Itest_lib $(MTARINC) -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200809L -CFLAGS = -std=c99 -Wall -Wextra -LDFLAGS = - -PROFRAW_FILE=$(TBIN).profraw -PROFDATA_FILE=$(TBIN).profdata - -export LLVM_PROFILE_FILE=$(PROFRAW_FILE) - -ifeq ($(COVERAGE),1) - CC = clang - CFLAGS += -g -Og -fprofile-instr-generate -fcoverage-mapping - LDFLAGS += -fprofile-instr-generate -fcoverage-mapping -else - CFLAGS += -O2 -endif - -ifeq ($(SANITIZE),1) - CFLAGS += -fsanitize=address -fsanitize=undefined - LDFLAGS += -fsanitize=address -fsanitize=undefined -endif - -.PHONY: all -all: $(LIB) $(TBIN) - -.PHONY: test -test: $(TBIN) - @./$(TBIN) - -.PHONY: cov -cov: $(PROFDATA_FILE) - @llvm-cov report $(TBIN) -instr-profile=$(PROFDATA_FILE) - -.PHONY: cov-show -cov-show: $(PROFDATA_FILE) - @llvm-cov show $(TBIN) --use-color -instr-profile=$(PROFDATA_FILE) $(f) | less -R - -.PHONY: clean -clean: - rm -f $(LIB) $(OBJ) - rm -f $(TBIN) $(TOBJ) - rm -f $(PROFRAW_FILE) $(PROFDATA_FILE) - rm -f fakeNAND.bin fakeNAND_meta.bin - -$(LIB): $(OBJ) - $(AR) rcs $@ $^ >/dev/null - -$(TBIN): $(TOBJ) $(LIB) $(MTARLIB) - $(CC) -o $@ $^ $(LDFLAGS) - -%.o: %.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ - -# use separate rule instead of depending on 'test' to avoid re-running -$(PROFRAW_FILE): $(TBIN) - @./$(TBIN) - -$(PROFDATA_FILE): $(PROFRAW_FILE) - @llvm-profdata merge -sparse $(PROFRAW_FILE) -o $(PROFDATA_FILE) diff --git a/lib/x1000-installer/SOURCES b/lib/x1000-installer/SOURCES deleted file mode 100644 index cdbd9148d8..0000000000 --- a/lib/x1000-installer/SOURCES +++ /dev/null @@ -1,6 +0,0 @@ -src/xf_error.c -src/xf_flashmap.c -src/xf_nandio.c -src/xf_package.c -src/xf_stream.c -src/xf_update.c diff --git a/lib/x1000-installer/include/xf_error.h b/lib/x1000-installer/include/xf_error.h deleted file mode 100644 index 2f3f6a1a4f..0000000000 --- a/lib/x1000-installer/include/xf_error.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_ERROR_H_ -#define _XF_ERROR_H_ - -enum { - XF_E_SUCCESS = 0, - XF_E_IO = -1, - XF_E_LINE_TOO_LONG = -2, - XF_E_FILENAME_TOO_LONG = -3, - XF_E_INT_OVERFLOW = -4, - XF_E_BUF_OVERFLOW = -5, - XF_E_SYNTAX_ERROR = -6, - XF_E_INVALID_PARAMETER = -7, - XF_E_NAND = -8, - XF_E_OUT_OF_MEMORY = -9, - XF_E_OUT_OF_RANGE = -10, - XF_E_VERIFY_FAILED = -11, - XF_E_CANNOT_OPEN_FILE = -12, -}; - -const char* xf_strerror(int err); - -#endif /* _XF_ERROR_H_ */ diff --git a/lib/x1000-installer/include/xf_flashmap.h b/lib/x1000-installer/include/xf_flashmap.h deleted file mode 100644 index b0470e58e0..0000000000 --- a/lib/x1000-installer/include/xf_flashmap.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_FLASHMAP_H_ -#define _XF_FLASHMAP_H_ - -#include "xf_stream.h" -#include - -#define XF_MAP_NAMELEN 63 - -enum { - XF_MAP_HAS_MD5 = 0x01, /* 'md5' field is valid */ - XF_MAP_HAS_FILE_LENGTH = 0x02, /* 'file_length' field is valid */ -}; - -struct xf_map { - char name[XF_MAP_NAMELEN+1]; /* file name */ - uint8_t md5[16]; /* MD5 sum of file */ - uint32_t file_length; /* length of file in bytes */ - uint32_t offset; /* offset in flash */ - uint32_t length; /* region length in flash, in bytes */ - int flags; -}; - -/* Parse a line with space- or tab-delimited fields of the form - * - * '-' - * - * - name can be up to XF_FMAP_NAMELEN characters long - * - md5 is 32 hexadecimal characters (case insensitive) - * - file_length, offset, and length are 32-bit unsigned integers - * and can be given in decimal or (with '0x' prefix) hexadecimal - * - * Parsed data is written to *map. Returns zero on success and - * nonzero on error. - */ -int xf_map_parseline(const char* line, struct xf_map* map); - -/* Parse a file calling xf_map_parseline() on each line to populate - * a map of up to 'maxnum' regions. Blank and comment lines are - * ignored (comments start with '#'). - * - * Returns the number of regions in the resulting map if the file was - * parsed successfully, or a negative value on error. - */ -int xf_map_parse(struct xf_stream* s, struct xf_map* map, int maxnum); - -/* Sort the map so its members are in ascending order with the lowest - * flash offset region first. After sorting, xf_map_validate() is used - * to check for overlapping regions. - * - * The return value is that of xf_map_validate(). - */ -int xf_map_sort(struct xf_map* map, int num); - -/* Check if the input map is sorted and contains no overlap. - * - * Returns 0 if the map is sorted and contains no overlapping regions, - * -1 if the map isn't sorted, or if an overlapping region is detected, - * the index of the first overlapping region. (A returned index i is - * always positive: the two overlapped entries are map[i] and map[i-1].) - */ -int xf_map_validate(const struct xf_map* map, int num); - -/* Write the map to a stream. This does not check that the map is valid. - * Returns the number of bytes written to the stream or a negative value - * on error. The stream may be NULL, in which case the number of bytes - * that would be written are returned (similar to snprintf). - */ -int xf_map_write(struct xf_map* map, int num, struct xf_stream* s); - -#endif /* _XF_FLASHMAP_H_ */ diff --git a/lib/x1000-installer/include/xf_nandio.h b/lib/x1000-installer/include/xf_nandio.h deleted file mode 100644 index a10b71992c..0000000000 --- a/lib/x1000-installer/include/xf_nandio.h +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_NANDIO_H_ -#define _XF_NANDIO_H_ - -#include "nand-x1000.h" -#include -#include - -enum xf_nandio_mode { - XF_NANDIO_READ = 0, - XF_NANDIO_PROGRAM, - XF_NANDIO_VERIFY, -}; - -struct xf_nandio { - nand_drv* ndrv; - int nand_err; /* copy of the last NAND error code */ - int alloc_handle; - enum xf_nandio_mode mode; - - size_t block_size; /* size of a block, in bytes */ - size_t page_size; /* size of a page, in bytes */ - - uint8_t* old_buf; /* contains the 'old' block data already on chip */ - uint8_t* new_buf; /* contains the possibly modified 'new' block data */ - - nand_block_t cur_block; /* address of the current block */ - size_t offset_in_block; /* byte offset in the current block */ - unsigned block_valid: 1; /* 1 if buffered block data is valid */ -}; - -int xf_nandio_init(struct xf_nandio* nio); -void xf_nandio_destroy(struct xf_nandio* nio); - -/** Sets the operational mode, which determines read/write/flush semantics. - * - * - XF_NANDIO_READ: Accesses the chip in read-only mode. Writes are allowed, - * but should not be used. (Writes will modify a temporary buffer but this - * will not alter the flash contents.) - * - * - XF_NANDIO_PROGRAM: Writes are allowed to modify the flash contents. - * Writes within a block are accumulated in a temporary buffer. When - * crossing a block boundary, either by writing past the end the current - * block or by seeking to a new one, the data written to the temporary - * buffer is compared against the current flash contents. If the block - * has been modified, it is erased and any non-blank pages are programmed - * with the new data. - * - * - XF_NANDIO_VERIFY: This mode allows callers to easily check whether the - * flash contents match some expected contents. Callers "write" the expected - * contents as if programming it with XF_NANDIO_PROGRAM. When a block is - * flushed, if the written data doesn't match the block contents, an - * XF_E_VERIFY_FAILED error is returned. The flash contents will not be - * altered in this mode. - * - * \returns XF_E_SUCCESS or a negative error code on failure. - */ -int xf_nandio_set_mode(struct xf_nandio* nio, enum xf_nandio_mode mode); - -/** Seek to a given byte offset in the NAND flash. - * - * If the new offset is outside the current block, the current block will - * be automatically flushed. Note this can result in verification or program - * failures as with any other flush. - * - * \returns XF_E_SUCCESS or a negative error code on failure. - */ -int xf_nandio_seek(struct xf_nandio* nio, size_t offset); - -/** Read or write a contiguous sequence of bytes from flash. - * - * The read or write starts at the current position and continues for `count` - * bytes. Both reads and writes may cross block boundaries. Modified blocks - * will be flushed automatically if the operation crosses a block boundary. - * - * After a successful read or write, the current position is advanced by - * exactly `count` bytes. After a failure, the position is indeterminate. - * - * \returns XF_E_SUCCESS or a negative error code on failure. - */ -int xf_nandio_read(struct xf_nandio* nio, void* buf, size_t count); -int xf_nandio_write(struct xf_nandio* nio, const void* buf, size_t count); - -/** Get a pointer to the block buffer for direct read/write access. - * - * These functions can be used to read or write data without intermediate - * buffers. The caller passes in the amount of data to be transferred in - * `*count`. A pointer to part of the block buffer is returned in `*buf` - * and the number of bytes available in `*buf` is returned in `*count`. - * - * Data at the current position can be read from the returned buffer and - * it may be modified by writing to the buffer. The buffer is only valid - * until the next call to an `xf_nandio` function. - * - * The read/write position is advanced by the returned `*count` on success, - * and is unchanged on failure. - * - * \returns XF_E_SUCCESS or a negative error code on failure. - */ -int xf_nandio_get_buffer(struct xf_nandio* nio, void** buf, size_t* count); - -/** Flush the buffered block to ensure all outstanding program or verification - * operations have been performed. This should only be called to ensure the - * final modified block is flushed after you have finished writing all data. - * - * \returns XF_E_SUCCESS or a negative error code on failure. - */ -int xf_nandio_flush(struct xf_nandio* nio); - -#endif /* _XF_NANDIO_H_ */ diff --git a/lib/x1000-installer/include/xf_package.h b/lib/x1000-installer/include/xf_package.h deleted file mode 100644 index 6633766bd7..0000000000 --- a/lib/x1000-installer/include/xf_package.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_PACKAGE_H_ -#define _XF_PACKAGE_H_ - -/* package format - * - * - bootloader-info.txt (contains a version label and optional metadata) - * - flashmap.txt (describes the flash update map) - * - [package must contain any other files referenced by the flash map] - * - [other files may be present, but are ignored] - */ - -#include "xf_flashmap.h" -#include "xf_stream.h" -#include "microtar.h" - -struct xf_package { - int alloc_handle; - mtar_t* tar; - struct xf_map* map; - int map_size; - char* metadata; - size_t metadata_len; -}; - -/** Open an update package - * - * \param pkg Uninitialized package structure - * \param file Name of the package file - * \param dflt_map Default flash map for loading old format packages - * \param dflt_map_size Size of the default flash map - * \returns XF_E_SUCCESS or a negative error code - */ -int xf_package_open_ex(struct xf_package* pkg, const char* file, - const struct xf_map* dflt_map, int dflt_map_size); - -/** Close a package which was previously opened successfully */ -void xf_package_close(struct xf_package* pkg); - -static inline int xf_package_open(struct xf_package* pkg, const char* file) -{ - return xf_package_open_ex(pkg, file, NULL, 0); -} - -#endif /* _XF_PACKAGE_H_ */ diff --git a/lib/x1000-installer/include/xf_stream.h b/lib/x1000-installer/include/xf_stream.h deleted file mode 100644 index adbde1c6db..0000000000 --- a/lib/x1000-installer/include/xf_stream.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_STREAM_H_ -#define _XF_STREAM_H_ - -#include -#include -#include /* ssize_t */ -#include "microtar.h" - -struct xf_stream; - -struct xf_stream_ops { - off_t(*xget_size)(struct xf_stream* s); - ssize_t(*xread)(struct xf_stream* s, void* buf, size_t len); - ssize_t(*xwrite)(struct xf_stream* s, const void* buf, size_t len); - int(*xclose)(struct xf_stream* s); -}; - -struct xf_stream { - intptr_t data; - const struct xf_stream_ops* ops; -}; - -inline size_t xf_stream_get_size(struct xf_stream* s) -{ return s->ops->xget_size(s); } - -inline ssize_t xf_stream_read(struct xf_stream* s, void* buf, size_t len) -{ return s->ops->xread(s, buf, len); } - -inline ssize_t xf_stream_write(struct xf_stream* s, const void* buf, size_t len) -{ return s->ops->xwrite(s, buf, len); } - -inline int xf_stream_close(struct xf_stream* s) -{ return s->ops->xclose(s); } - -int xf_open_file(const char* file, int flags, struct xf_stream* s); -int xf_open_tar(mtar_t* mtar, const char* file, struct xf_stream* s); -int xf_create_tar(mtar_t* mtar, const char* file, size_t size, struct xf_stream* s); - -/* Utility function needed for a few things */ -int xf_stream_read_lines(struct xf_stream* s, char* buf, size_t bufsz, - int(*callback)(int n, char* buf, void* arg), void* arg); - -#endif /* _XF_STREAM_H_ */ diff --git a/lib/x1000-installer/include/xf_update.h b/lib/x1000-installer/include/xf_update.h deleted file mode 100644 index e421a21793..0000000000 --- a/lib/x1000-installer/include/xf_update.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _XF_UPDATE_H_ -#define _XF_UPDATE_H_ - -#include "xf_package.h" -#include "xf_nandio.h" -#include "xf_flashmap.h" - -typedef int(*xf_update_open_stream_cb)(void* arg, const char* file, - struct xf_stream* stream); - -enum xf_update_mode { - XF_UPDATE, - XF_BACKUP, - XF_VERIFY, -}; - -/** The main updater entry point - * - * \param mode Operational mode - * \param nio Initialized NAND I/O object. - * \param map Flash map describing what regions to update. - * \param map_size Number of entries in the map. - * \param open_stream Callback used to open a stream for each map entry. - * \param arg Argument passed to the `open_stream` callback. - * - * \returns XF_E_SUCCESS on success or a negative error code on failure. - */ -int xf_updater_run(enum xf_update_mode mode, struct xf_nandio* nio, - struct xf_map* map, int map_size, - xf_update_open_stream_cb open_stream, void* arg); - -#endif /* _XF_UPDATE_H_ */ diff --git a/lib/x1000-installer/src/xf_error.c b/lib/x1000-installer/src/xf_error.c deleted file mode 100644 index 3d4b342a92..0000000000 --- a/lib/x1000-installer/src/xf_error.c +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_error.h" - -const char* xf_strerror(int err) -{ - switch(err) { - case XF_E_SUCCESS: return "Success"; - case XF_E_IO: return "I/O error"; - case XF_E_LINE_TOO_LONG: return "Line too long"; - case XF_E_FILENAME_TOO_LONG: return "Filename too long"; - case XF_E_INT_OVERFLOW: return "Numeric overflow"; - case XF_E_BUF_OVERFLOW: return "Buffer overflowed"; - case XF_E_SYNTAX_ERROR: return "Syntax error"; - case XF_E_INVALID_PARAMETER: return "Invalid parameter"; - case XF_E_NAND: return "NAND flash error"; - case XF_E_OUT_OF_MEMORY: return "Out of memory"; - case XF_E_OUT_OF_RANGE: return "Out of range"; - case XF_E_VERIFY_FAILED: return "Verification failed"; - case XF_E_CANNOT_OPEN_FILE: return "Cannot open file"; - default: return "Unknown error"; - } -} diff --git a/lib/x1000-installer/src/xf_flashmap.c b/lib/x1000-installer/src/xf_flashmap.c deleted file mode 100644 index 972bf320ad..0000000000 --- a/lib/x1000-installer/src/xf_flashmap.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_flashmap.h" -#include "xf_error.h" -#include -#include -#include -#include - -static int xdigit_to_int(char c) -{ - if(c >= 'a' && c <= 'f') - return 10 + (c - 'a'); - if(c >= 'A' && c <= 'F') - return 10 + (c - 'A'); - if(c >= '0' && c <= '9') - return c - '0'; - return -1; -} - -static int isfilenamechar(char c) -{ - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == '$' || c == '%' || c == '\'' || c == '-' || c == '_' || - c == '@' || c == '~' || c == '`' || c == '!' || c == '(' || - c == ')' || c == '{' || c == '}' || c == '^' || c == '#' || - c == '&' || c == '+' || c == ',' || c == ';' || c == '=' || - c == '[' || c == ']' || c == '.'; -} - -int xf_map_parseline(const char* line, struct xf_map* map) -{ - enum { - s_name, - s_md5, - s_first_num, - s_file_len = s_first_num, - s_offset, - s_length, - s_done, - }; - -#define skipws() do { while(*line == ' ' || *line == '\t') ++line; } while(0) -#define nextstate() do { ++state; length = 0; ++line; skipws(); } while(0) - - int state = s_name; - int length = 0; - int digit_val; - uint32_t int_val; - uint32_t* num_ptr[3] = {&map->file_length, &map->offset, &map->length}; - bool has_md5 = true; - - skipws(); - while(*line && *line != '\n') { - switch(state) { - case s_name: - if(*line == ' ' || *line == '\t') { - nextstate(); - continue; - } else if(isfilenamechar(*line)) { - if(length == XF_MAP_NAMELEN) - return XF_E_FILENAME_TOO_LONG; - - map->name[length++] = *line++; - map->name[length] = '\0'; - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_md5: - if(*line == '-') { - memset(map->md5, 0, 16); - map->file_length = 0; - has_md5 = false; - ++line; - } else { - for(int i = 0; i < 16; ++i) { - int_val = 0; - for(int j = 0; j < 2; ++j) { - digit_val = xdigit_to_int(*line++); - if(digit_val < 0) - return XF_E_SYNTAX_ERROR; - - int_val <<= 4; - int_val |= digit_val; - } - - map->md5[i] = int_val; - } - } - - if(*line == ' ' || *line == '\t') { - /* skip file length if md5 is not present */ - if(!has_md5) - ++state; - - nextstate(); - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_file_len: - case s_offset: - case s_length: - int_val = 0; - - if(*line == '0') { - ++line; - if(*line == 'x' || *line == 'X') { - ++line; - while((digit_val = xdigit_to_int(*line)) >= 0) { - ++line; - - if(int_val > UINT32_MAX/16) - return XF_E_INT_OVERFLOW; - - int_val *= 16; - int_val |= digit_val; - } - } - } else if(*line >= '1' && *line <= '9') { - do { - if(int_val > UINT32_MAX/10) - return XF_E_INT_OVERFLOW; - int_val *= 10; - - digit_val = *line++ - '0'; - if(int_val > UINT32_MAX - digit_val) - return XF_E_INT_OVERFLOW; - - int_val += digit_val; - } while(*line >= '0' && *line <= '9'); - } - - *num_ptr[state - s_first_num] = int_val; - - if(*line == ' ' || *line == '\t') { - nextstate(); - continue; - } else if(state+1 == s_done && *line == '\0') { - /* end of input */ - continue; - } else { - return XF_E_SYNTAX_ERROR; - } - - case s_done: - if(isspace(*line)) { - line++; - continue; /* swallow trailing spaces, carriage return, etc */ - } else - return XF_E_SYNTAX_ERROR; - } - } - -#undef skipws -#undef nextstate - - /* one last overflow check - ensure mapped range is addressable */ - if(map->offset > UINT32_MAX - map->length) - return XF_E_INT_OVERFLOW; - - if(has_md5) - map->flags = XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH; - else - map->flags = 0; - - return XF_E_SUCCESS; -} - -struct map_parse_args { - struct xf_map* map; - int num; - int maxnum; -}; - -int map_parse_line_cb(int n, char* buf, void* arg) -{ - (void)n; - - struct map_parse_args* args = arg; - - /* skip whitespace */ - while(*buf && isspace(*buf)) - ++buf; - - /* ignore comments and blank lines */ - if(*buf == '#' || *buf == '\0') - return 0; - - struct xf_map dummy_map; - struct xf_map* dst_map; - if(args->num < args->maxnum) - dst_map = &args->map[args->num]; - else - dst_map = &dummy_map; - - int rc = xf_map_parseline(buf, dst_map); - if(rc) - return rc; - - args->num++; - return 0; -} - -int xf_map_parse(struct xf_stream* s, struct xf_map* map, int maxnum) -{ - char buf[200]; - struct map_parse_args args; - args.map = map; - args.num = 0; - args.maxnum = maxnum; - - int rc = xf_stream_read_lines(s, buf, sizeof(buf), - map_parse_line_cb, &args); - if(rc < 0) - return rc; - - return args.num; -} - -static int xf_map_compare(const void* a, const void* b) -{ - const struct xf_map* mapA = a; - const struct xf_map* mapB = b; - - if(mapA->offset < mapB->offset) - return -1; - else if(mapA->offset == mapB->offset) - return 0; - else - return 1; -} - -int xf_map_sort(struct xf_map* map, int num) -{ - qsort(map, num, sizeof(struct xf_map), xf_map_compare); - return xf_map_validate(map, num); -} - -int xf_map_validate(const struct xf_map* map, int num) -{ - for(int i = 1; i < num; ++i) - if(map[i].offset <= map[i-1].offset) - return -1; - - for(int i = 1; i < num; ++i) - if(map[i-1].offset + map[i-1].length > map[i].offset) - return i; - - return 0; -} - -int xf_map_write(struct xf_map* map, int num, struct xf_stream* s) -{ - static const char hex[] = "0123456789abcdef"; - char buf[200]; - char md5str[33]; - int total_len = 0; - - md5str[32] = '\0'; - - for(int i = 0; i < num; ++i) { - bool has_md5 = false; - if(map->flags & XF_MAP_HAS_MD5) { - if(!(map->flags & XF_MAP_HAS_FILE_LENGTH)) - return XF_E_INVALID_PARAMETER; - - has_md5 = true; - for(int j = 0; j < 16; ++j) { - uint8_t byte = map[i].md5[j]; - md5str[2*j] = hex[(byte >> 4) & 0xf]; - md5str[2*j+1] = hex[byte & 0xf]; - } - } - - int len; - if(!has_md5) { - len = snprintf(buf, sizeof(buf), "%s - %lx %lu\n", - map[i].name, - (unsigned long)map[i].offset, - (unsigned long)map[i].length); - } else { - len = snprintf(buf, sizeof(buf), "%s %s %lu 0x%lx %lu\n", - map[i].name, md5str, - (unsigned long)map[i].file_length, - (unsigned long)map[i].offset, - (unsigned long)map[i].length); - } - - if(len < 0 || (size_t)len >= sizeof(buf)) - return XF_E_LINE_TOO_LONG; - - if(s) { - int rc = xf_stream_write(s, buf, len); - if(rc != len) - return XF_E_IO; - } - - total_len += len; - } - - return total_len; -} diff --git a/lib/x1000-installer/src/xf_nandio.c b/lib/x1000-installer/src/xf_nandio.c deleted file mode 100644 index 6dc87bc420..0000000000 --- a/lib/x1000-installer/src/xf_nandio.c +++ /dev/null @@ -1,292 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_nandio.h" -#include "xf_error.h" -#include "core_alloc.h" -#include "system.h" -#include -#include - -int xf_nandio_init(struct xf_nandio* nio) -{ - int rc; - - memset(nio, 0, sizeof(*nio)); - - /* open NAND */ - nio->ndrv = nand_init(); - nand_lock(nio->ndrv); - rc = nand_open(nio->ndrv); - if(rc != NAND_SUCCESS) { - nio->nand_err = rc; - rc = XF_E_NAND; - goto out; - } - - /* read chip parameters */ - nio->page_size = nio->ndrv->chip->page_size; - nio->block_size = nio->page_size << nio->ndrv->chip->log2_ppb; - - /* allocate memory */ - size_t alloc_size = 0; - alloc_size += CACHEALIGN_SIZE - 1; - alloc_size += nio->block_size * 2; - - nio->alloc_handle = core_alloc_ex("xf_nandio", alloc_size, &buflib_ops_locked); - if(nio->alloc_handle < 0) { - rc = XF_E_OUT_OF_MEMORY; - goto out_nclose; - } - - uint8_t* buffer = core_get_data(nio->alloc_handle); - CACHEALIGN_BUFFER(buffer, alloc_size); - - nio->old_buf = buffer; - nio->new_buf = &buffer[nio->block_size]; - - rc = XF_E_SUCCESS; - goto out; - - out_nclose: - nand_close(nio->ndrv); - out: - nand_unlock(nio->ndrv); - return rc; -} - -void xf_nandio_destroy(struct xf_nandio* nio) -{ - nio->alloc_handle = core_free(nio->alloc_handle); - - if(nio->ndrv) { - nand_lock(nio->ndrv); - nand_close(nio->ndrv); - nand_unlock(nio->ndrv); - nio->ndrv = NULL; - } -} - -static bool is_page_blank(const uint8_t* buf, uint32_t length) -{ - for(uint32_t i = 0; i < length; ++i) - if(buf[i] != 0xff) - return false; - - return true; -} - -static int flush_block(struct xf_nandio* nio, bool invalidate) -{ - /* no block, or only reading - flush is a no-op */ - if(!nio->block_valid || nio->mode == XF_NANDIO_READ) - return XF_E_SUCCESS; - - /* nothing to do if new data is same as old data */ - if(!memcmp(nio->old_buf, nio->new_buf, nio->block_size)) - return XF_E_SUCCESS; - - /* data mismatch during verification - report the error */ - if(nio->mode == XF_NANDIO_VERIFY) - return XF_E_VERIFY_FAILED; - - /* erase the block */ - int rc = nand_block_erase(nio->ndrv, nio->cur_block); - if(rc != NAND_SUCCESS) { - nio->block_valid = false; - nio->nand_err = rc; - return XF_E_NAND; - } - - size_t oob_size = nio->ndrv->chip->oob_size; - - unsigned page = 0; - nand_page_t page_addr = nio->cur_block; - for(; page < nio->ndrv->ppb; ++page, ++page_addr) { - /* skip programming blank pages to go faster & reduce wear */ - uint8_t* page_data = &nio->new_buf[page * nio->page_size]; - if(is_page_blank(page_data, nio->page_size)) - continue; - - /* copy page and write blank OOB data */ - memcpy(nio->ndrv->page_buf, page_data, nio->page_size); - memset(&nio->ndrv->page_buf[nio->page_size], 0xff, oob_size); - - /* program the page */ - rc = nand_page_program(nio->ndrv, page_addr, nio->ndrv->page_buf); - if(rc != NAND_SUCCESS) { - nio->block_valid = false; - nio->nand_err = rc; - return XF_E_NAND; - } - } - - if(invalidate) - nio->block_valid = false; - else { - /* update our 'old' buffer so a subsequent flush - * will not reprogram the same block */ - memcpy(nio->old_buf, nio->new_buf, nio->block_size); - } - - return XF_E_SUCCESS; -} - -static int seek_to_block(struct xf_nandio* nio, nand_block_t block_addr, - size_t offset_in_block) -{ - /* already on this block? */ - if(nio->block_valid && block_addr == nio->cur_block) { - nio->offset_in_block = offset_in_block; - return XF_E_SUCCESS; - } - - /* ensure new block is within range */ - if(block_addr >= (nio->ndrv->chip->nr_blocks << nio->ndrv->chip->log2_ppb)) - return XF_E_OUT_OF_RANGE; - - /* flush old block */ - int rc = flush_block(nio, true); - if(rc) - return rc; - - nio->block_valid = false; - - /* read the new block */ - unsigned page = 0; - nand_page_t page_addr = block_addr; - for(; page < nio->ndrv->ppb; ++page, ++page_addr) { - rc = nand_page_read(nio->ndrv, page_addr, nio->ndrv->page_buf); - if(rc != NAND_SUCCESS) { - nio->nand_err = rc; - return XF_E_NAND; - } - - memcpy(&nio->old_buf[page * nio->page_size], nio->ndrv->page_buf, nio->page_size); - } - - /* copy to 2nd buffer */ - memcpy(nio->new_buf, nio->old_buf, nio->block_size); - - /* update position */ - nio->cur_block = block_addr; - nio->offset_in_block = offset_in_block; - nio->block_valid = true; - return XF_E_SUCCESS; -} - -int xf_nandio_set_mode(struct xf_nandio* nio, enum xf_nandio_mode mode) -{ - nand_lock(nio->ndrv); - - /* flush the current block before switching to the new mode, - * to ensure consistency */ - int rc = flush_block(nio, false); - if(rc) - goto err; - - nio->mode = mode; - rc = XF_E_SUCCESS; - - err: - nand_unlock(nio->ndrv); - return rc; -} - -static int nandio_rdwr(struct xf_nandio* nio, void* buf, size_t count, bool write) -{ - while(count > 0) { - void* ptr; - size_t amount = count; - int rc = xf_nandio_get_buffer(nio, &ptr, &amount); - if(rc) - return rc; - - if(write) - memcpy(ptr, buf, amount); - else - memcpy(buf, ptr, amount); - - count -= amount; - } - - return XF_E_SUCCESS; -} - -int xf_nandio_seek(struct xf_nandio* nio, size_t offset) -{ - uint32_t block_nr = offset / nio->block_size; - size_t offset_in_block = offset % nio->block_size; - nand_block_t block_addr = block_nr << nio->ndrv->chip->log2_ppb; - - nand_lock(nio->ndrv); - int rc = seek_to_block(nio, block_addr, offset_in_block); - nand_unlock(nio->ndrv); - - return rc; -} - -int xf_nandio_read(struct xf_nandio* nio, void* buf, size_t count) -{ - return nandio_rdwr(nio, buf, count, false); -} - -int xf_nandio_write(struct xf_nandio* nio, const void* buf, size_t count) -{ - return nandio_rdwr(nio, (void*)buf, count, true); -} - -int xf_nandio_get_buffer(struct xf_nandio* nio, void** buf, size_t* count) -{ - nand_lock(nio->ndrv); - - /* make sure the current block data is read in */ - int rc = seek_to_block(nio, nio->cur_block, nio->offset_in_block); - if(rc) - goto err; - - size_t amount_left = nio->block_size - nio->offset_in_block; - if(amount_left == 0) { - amount_left = nio->block_size; - rc = seek_to_block(nio, nio->cur_block + nio->ndrv->ppb, 0); - if(rc) - goto err; - } - - *buf = &nio->new_buf[nio->offset_in_block]; - *count = MIN(*count, amount_left); - - nio->offset_in_block += *count; - rc = XF_E_SUCCESS; - - err: - nand_unlock(nio->ndrv); - return rc; -} - -int xf_nandio_flush(struct xf_nandio* nio) -{ - nand_lock(nio->ndrv); - int rc = flush_block(nio, false); - nand_unlock(nio->ndrv); - - return rc; -} diff --git a/lib/x1000-installer/src/xf_package.c b/lib/x1000-installer/src/xf_package.c deleted file mode 100644 index fb107aef72..0000000000 --- a/lib/x1000-installer/src/xf_package.c +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_package.h" -#include "xf_error.h" -#include "pathfuncs.h" -#include "file.h" -#include "core_alloc.h" -#include "md5.h" -#include "system.h" -#include -#include - -#ifdef ROCKBOX -# include "microtar-rockbox.h" -#else -# include "microtar-stdio.h" -#endif - -#define METADATA_SIZE 4096 /* size of the metadata buffer */ -#define MAX_MAP_SIZE 32 /* maximum number of map entries */ - -static int pkg_alloc(struct xf_package* pkg) -{ - memset(pkg, 0, sizeof(*pkg)); - - /* calculate allocation size */ - size_t alloc_size = 0; - alloc_size += ALIGN_UP_P2(sizeof(mtar_t), 3); - alloc_size += ALIGN_UP_P2(sizeof(struct xf_map) * MAX_MAP_SIZE, 3); - alloc_size += ALIGN_UP_P2(METADATA_SIZE, 3); - alloc_size += 7; /* for alignment */ - - pkg->alloc_handle = core_alloc_ex("xf_package", alloc_size, &buflib_ops_locked); - if(pkg->alloc_handle < 0) - return XF_E_OUT_OF_MEMORY; - - /* distribute memory */ - uint8_t* buf = (uint8_t*)core_get_data(pkg->alloc_handle); - memset(buf, 0, alloc_size); - ALIGN_BUFFER(buf, alloc_size, 8); - - pkg->tar = (mtar_t*)buf; - buf += ALIGN_UP_P2(sizeof(mtar_t), 3); - - pkg->map = (struct xf_map*)buf; - buf += ALIGN_UP_P2(sizeof(struct xf_map) * MAX_MAP_SIZE, 3); - - pkg->metadata = (char*)buf; - buf += ALIGN_UP_P2(METADATA_SIZE, 3); - - return XF_E_SUCCESS; -} - -static int read_meta_line_cb(int n, char* buf, void* arg) -{ - struct xf_package* pkg = (struct xf_package*)arg; - size_t length = strlen(buf); - - /* skip blank lines and the first line (it's reserved for old format) */ - if(n == 0 || length == 0) - return 0; - - /* metadata lines require an '=' sign to separate key and value */ - if(!strchr(buf, '=')) - return XF_E_SYNTAX_ERROR; - - /* we need space to copy the key-value pair plus a null terminator */ - if(length + 1 >= METADATA_SIZE - pkg->metadata_len) - return XF_E_BUF_OVERFLOW; - - memcpy(&pkg->metadata[pkg->metadata_len], buf, length + 1); - pkg->metadata_len += length + 1; - return 0; -} - -static int pkg_read_meta(struct xf_package* pkg) -{ - struct xf_stream stream; - int rc = xf_open_tar(pkg->tar, "bootloader-info.txt", &stream); - if(rc) - return XF_E_CANNOT_OPEN_FILE; - - char buf[200]; - rc = xf_stream_read_lines(&stream, buf, sizeof(buf), read_meta_line_cb, pkg); - xf_stream_close(&stream); - return rc; -} - -static int pkg_read_map(struct xf_package* pkg, - const struct xf_map* dflt_map, int dflt_map_size) -{ - /* Attempt to load and parse the map file */ - struct xf_stream stream; - int rc = xf_open_tar(pkg->tar, "flashmap.txt", &stream); - - /* If the flash map is absent but a default map has been provided, - * then the update is in the old fixed format. */ - if(rc == MTAR_ENOTFOUND && dflt_map) { - if(dflt_map_size > MAX_MAP_SIZE) - return XF_E_INVALID_PARAMETER; - - for(int i = 0; i < dflt_map_size; ++i) { - pkg->map[i] = dflt_map[i]; - pkg->map[i].flags &= ~(XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH); - } - - pkg->map_size = dflt_map_size; - return XF_E_SUCCESS; - } - - if(rc != MTAR_ESUCCESS) - return XF_E_CANNOT_OPEN_FILE; - - rc = xf_map_parse(&stream, pkg->map, MAX_MAP_SIZE); - if(rc < 0) - goto err; - - /* Sort the map; reject it if there is any overlap. */ - pkg->map_size = rc; - if(xf_map_sort(pkg->map, pkg->map_size)) { - rc = XF_E_INVALID_PARAMETER; - goto err; - } - - /* All packages in the 'new' format are required to have MD5 sums. */ - for(int i = 0; i < pkg->map_size; ++i) { - if(!(pkg->map[i].flags & XF_MAP_HAS_MD5) || - !(pkg->map[i].flags & XF_MAP_HAS_FILE_LENGTH)) { - rc = XF_E_VERIFY_FAILED; - goto err; - } - } - - rc = XF_E_SUCCESS; - - err: - xf_stream_close(&stream); - return rc; -} - -static int pkg_verify(struct xf_package* pkg) -{ - struct xf_stream stream; - md5_context ctx; - uint8_t buffer[128]; - - for(int i = 0; i < pkg->map_size; ++i) { - /* At a bare minimum, check that the file exists. */ - int rc = xf_open_tar(pkg->tar, pkg->map[i].name, &stream); - if(rc) - return XF_E_VERIFY_FAILED; - - /* Also check that it isn't bigger than the update region. - * That would normally indicate a problem. */ - off_t streamsize = xf_stream_get_size(&stream); - if(streamsize > (off_t)pkg->map[i].length) { - rc = XF_E_VERIFY_FAILED; - goto err; - } - - /* Check against the listed file length. */ - if(pkg->map[i].flags & XF_MAP_HAS_FILE_LENGTH) { - if(streamsize != (off_t)pkg->map[i].file_length) { - rc = XF_E_VERIFY_FAILED; - goto err; - } - } - - /* Check the MD5 sum if we have it. */ - if(pkg->map[i].flags & XF_MAP_HAS_MD5) { - md5_starts(&ctx); - while(1) { - ssize_t n = xf_stream_read(&stream, buffer, sizeof(buffer)); - if(n < 0) { - rc = XF_E_IO; - goto err; - } - - md5_update(&ctx, buffer, n); - if((size_t)n < sizeof(buffer)) - break; - } - - md5_finish(&ctx, buffer); - if(memcpy(buffer, pkg->map[i].md5, 16)) { - rc = XF_E_VERIFY_FAILED; - goto err; - } - } - - err: - xf_stream_close(&stream); - if(rc) - return rc; - } - - /* All files passed verification */ - return XF_E_SUCCESS; -} - -int xf_package_open_ex(struct xf_package* pkg, const char* file, - const struct xf_map* dflt_map, int dflt_map_size) -{ - int rc = pkg_alloc(pkg); - if(rc) - return rc; - -#ifdef ROCKBOX - rc = mtar_open(pkg->tar, file, O_RDONLY); -#else - rc = mtar_open(pkg->tar, file, "r"); -#endif - if(rc != MTAR_ESUCCESS) { - rc = XF_E_CANNOT_OPEN_FILE; - goto err; - } - - rc = pkg_read_meta(pkg); - if(rc) - goto err; - - rc = pkg_read_map(pkg, dflt_map, dflt_map_size); - if(rc) - goto err; - - rc = pkg_verify(pkg); - if(rc) - goto err; - - err: - if(rc) - xf_package_close(pkg); - return rc; -} - -void xf_package_close(struct xf_package* pkg) -{ - if(mtar_is_open(pkg->tar)) - mtar_close(pkg->tar); - - pkg->alloc_handle = core_free(pkg->alloc_handle); -} diff --git a/lib/x1000-installer/src/xf_stream.c b/lib/x1000-installer/src/xf_stream.c deleted file mode 100644 index b6391b2c8d..0000000000 --- a/lib/x1000-installer/src/xf_stream.c +++ /dev/null @@ -1,211 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_stream.h" -#include "xf_error.h" -#include "file.h" -#include -#include -#include - -/* - * File streams - */ - -static off_t file_stream_get_size(struct xf_stream* s) -{ - return filesize(s->data); -} - -static ssize_t file_stream_read(struct xf_stream* s, void* buf, size_t len) -{ - return read(s->data, buf, len); -} - -static ssize_t file_stream_write(struct xf_stream* s, const void* buf, size_t len) -{ - return write(s->data, buf, len); -} - -static int file_stream_close(struct xf_stream* s) -{ - return close(s->data); -} - -static const struct xf_stream_ops file_stream_ops = { - .xget_size = file_stream_get_size, - .xread = file_stream_read, - .xwrite = file_stream_write, - .xclose = file_stream_close, -}; - -int xf_open_file(const char* file, int flags, struct xf_stream* s) -{ - s->data = open(file, flags, 0666); - s->ops = &file_stream_ops; - return (s->data >= 0) ? 0 : -1; -} - -/* - * Tar streams - */ - -static off_t tar_stream_get_size(struct xf_stream* s) -{ - mtar_t* mtar = (mtar_t*)s->data; - return mtar_get_header(mtar)->size; -} - -static ssize_t tar_stream_read(struct xf_stream* s, void* buffer, size_t count) -{ - mtar_t* mtar = (mtar_t*)s->data; - - int ret = mtar_read_data(mtar, buffer, count); - if(ret < 0) - return -1; - - return ret; -} - -static ssize_t tar_stream_write(struct xf_stream* s, const void* buffer, size_t count) -{ - mtar_t* mtar = (mtar_t*)s->data; - - int ret = mtar_write_data(mtar, buffer, count); - if(ret < 0) - return -1; - - return ret; -} - -static int tar_stream_close(struct xf_stream* s) -{ - mtar_t* mtar = (mtar_t*)s->data; - - if(mtar_access_mode(mtar) == MTAR_WRITE) { - if(mtar_update_file_size(mtar) != MTAR_ESUCCESS) - return -1; - if(mtar_end_data(mtar) != MTAR_ESUCCESS) - return -1; - } - - return 0; -} - -static const struct xf_stream_ops tar_stream_ops = { - .xget_size = tar_stream_get_size, - .xread = tar_stream_read, - .xwrite = tar_stream_write, - .xclose = tar_stream_close, -}; - -int xf_open_tar(mtar_t* mtar, const char* file, struct xf_stream* s) -{ - int err = mtar_find(mtar, file); - if(err != MTAR_ESUCCESS) - return err; - - /* must only read normal files */ - const mtar_header_t* h = mtar_get_header(mtar); - if(h->type != 0 && h->type != MTAR_TREG) - return MTAR_EFAILURE; - - s->data = (intptr_t)mtar; - s->ops = &tar_stream_ops; - return MTAR_ESUCCESS; -} - -int xf_create_tar(mtar_t* mtar, const char* file, size_t size, struct xf_stream* s) -{ - int err = mtar_write_file_header(mtar, file, size); - if(err) - return err; - - s->data = (intptr_t)mtar; - s->ops = &tar_stream_ops; - return MTAR_ESUCCESS; -} - -/* - * Utility functions - */ - -int xf_stream_read_lines(struct xf_stream* s, char* buf, size_t bufsz, - int(*callback)(int n, char* buf, void* arg), void* arg) -{ - char* startp, *endp; - ssize_t bytes_read; - int rc; - - int n = 0; - size_t pos = 0; - bool at_eof = false; - - if(bufsz <= 1) - return XF_E_LINE_TOO_LONG; - - while(!at_eof) { - bytes_read = xf_stream_read(s, &buf[pos], bufsz - pos - 1); - if(bytes_read < 0) - return XF_E_IO; - - /* short read is end of file */ - if((size_t)bytes_read < bufsz - pos - 1) - at_eof = true; - - pos += bytes_read; - buf[pos] = '\0'; - - startp = endp = buf; - while(endp != &buf[pos]) { - endp = strchr(startp, '\n'); - if(endp) { - *endp = '\0'; - } else { - if(!at_eof) { - if(startp == buf) - return XF_E_LINE_TOO_LONG; - else - break; /* read ahead to look for newline */ - } else { - if(startp == &buf[pos]) - break; /* nothing left to do */ - else - endp = &buf[pos]; /* last line missing a newline - - * treat EOF as newline */ - } - } - - rc = callback(n++, startp, arg); - if(rc != 0) - return rc; - - startp = endp + 1; - } - - if(startp <= &buf[pos]) { - memmove(buf, startp, &buf[pos] - startp); - pos = &buf[pos] - startp; - } - } - - return 0; -} diff --git a/lib/x1000-installer/src/xf_update.c b/lib/x1000-installer/src/xf_update.c deleted file mode 100644 index 5a7c3b0430..0000000000 --- a/lib/x1000-installer/src/xf_update.c +++ /dev/null @@ -1,149 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "xf_update.h" -#include "xf_error.h" -#include "file.h" -#include "md5.h" -#include - -static int process_stream(struct xf_nandio* nio, - struct xf_map* map, - struct xf_stream* stream) -{ - void* buffer; - size_t count; - int rc; - - /* calculate MD5 on the fly if taking a backup */ - md5_context md5_ctx; - if(nio->mode == XF_NANDIO_READ) - md5_starts(&md5_ctx); - - /* first deal with the file data */ - size_t bytes_left = map->length; - while(bytes_left > 0) { - count = bytes_left; - rc = xf_nandio_get_buffer(nio, &buffer, &count); - if(rc) - return rc; - - if(nio->mode == XF_NANDIO_READ) { - md5_update(&md5_ctx, buffer, count); - rc = xf_stream_write(stream, buffer, count); - } else { - rc = xf_stream_read(stream, buffer, count); - } - - bytes_left -= count; - - if(rc < 0 || (size_t)rc > count) - return XF_E_IO; - - if((size_t)rc < count) { - /* backup - we could not write all the data */ - if(nio->mode == XF_NANDIO_READ) - return XF_E_IO; - - /* update - clear rest of buffer to 0xff */ - memset(buffer + rc, 0xff, count - rc); - break; - } - } - - /* if updating - write blanks to the remainder of the region */ - while(bytes_left > 0) { - count = bytes_left; - rc = xf_nandio_get_buffer(nio, &buffer, &count); - if(rc) - return rc; - - memset(buffer, 0xff, count); - bytes_left -= count; - } - - /* finalize the MD5 sum */ - if(nio->mode == XF_NANDIO_READ) { - md5_finish(&md5_ctx, map->md5); - map->file_length = map->length; - map->flags |= XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH; - } - - return XF_E_SUCCESS; -} - -static int process_map(struct xf_nandio* nio, struct xf_map* map, int map_size, - xf_update_open_stream_cb open_stream, void* os_arg) -{ - int rc, rc2; - struct xf_stream stream; - - /* ensure the map is sequential and non-overlapping before continuing */ - if(xf_map_validate(map, map_size) != 0) - return XF_E_INVALID_PARAMETER; - - for(int i = 0; i < map_size; ++i) { - /* seek to initial offset */ - rc = xf_nandio_seek(nio, map[i].offset); - if(rc) - return rc; - - rc = open_stream(os_arg, map[i].name, &stream); - if(rc) - return XF_E_CANNOT_OPEN_FILE; - - /* process the stream and be sure to close it even on error */ - rc = process_stream(nio, &map[i], &stream); - rc2 = xf_stream_close(&stream); - - /* bail if either operation raised an error */ - if(rc) - return rc; - if(rc2) - return rc2; - } - - /* now flush to ensure all data was written */ - rc = xf_nandio_flush(nio); - if(rc) - return rc; - - return XF_E_SUCCESS; -} - -static const enum xf_nandio_mode update_mode_to_nandio[] = { - [XF_UPDATE] = XF_NANDIO_PROGRAM, - [XF_BACKUP] = XF_NANDIO_READ, - [XF_VERIFY] = XF_NANDIO_VERIFY, -}; - -int xf_updater_run(enum xf_update_mode mode, struct xf_nandio* nio, - struct xf_map* map, int map_size, - xf_update_open_stream_cb open_stream, void* arg) -{ - /* Switch NAND I/O into the correct mode */ - int rc = xf_nandio_set_mode(nio, update_mode_to_nandio[mode]); - if(rc) - return rc; - - /* This does all the real work */ - return process_map(nio, map, map_size, open_stream, arg); -} diff --git a/lib/x1000-installer/test/data/lines_shuffled.txt b/lib/x1000-installer/test/data/lines_shuffled.txt deleted file mode 100644 index c138fe7e7c..0000000000 --- a/lib/x1000-installer/test/data/lines_shuffled.txt +++ /dev/null @@ -1,108 +0,0 @@ -1234567890abcdefghijklmnopqrstuvw -1234567890abcdefghijklmnopqrst -123 -1234567890abcdef -1234567890abcdefghijklm -1234567890abcdefghijklmn -1234567890abcdefghijk -1234567890abcdefgh -123456 -1234567 -1234567890a -1234567890abcdefghijklm -1 -1234567890abcdefghijklmnopq -1234567890abcdefghijkl -1234567890abcdefghijklmno -1234567890abcdefghijklmnopqrstuvwxyz -1234567890abcdefghijklmnopq -1234567890abcdefghijklmno -1234567890abcdefghijklmnopq -1234567890abcdefghijklmn -1234 -1234567890abcdefghijklmnop -123456789 -1234 -12345 -1234567890ab -1234567890abcdefghijklmnopqrstuvwxy -1234567890abcdefghijklmnopqrst -1234567890abcdefghijklmnopqrs -1234567890abcdefghijklmnopqrs -12345678 -1234567890ab -1234567890a -1234567890abcdefghijklmnopqr -123456 -1234567890abcdefghijkl -1234567890abcdefghijklm -1234567890abcdefghijklmnopqrstuvwxy -1234567890abcdefghijklmnopqrstuvwxy -1234567890abcdefghijklmnopqrstuv -1234567890abcdefghijklmnopqrstuv -1234567890abcdefghijklmnopqrstuvwx -1234567890abcde -1 -1234567890abcdefgh -1234567890abcdef -1234567890abcdefghi -1234567890 -1 -12345 -123456789 -1234567 -1234567890abcdefghi -1234567890abcdefghijklmnopqrstu -1234567890abcdefghijklmnopqrstuvwx -1234567890abcdefghijklmnopqrstuv -1234567890abcd -12345 -1234567890abcdefg -1234567890abcd -1234567890abcdefghijklmnopqrstuvw -1234567890abcdefghijklmnopqrstuvwxyz -12345678 -1234567890abcd -1234567890abcdefghijklmnop -123 -1234567890abcdefg -123456 -1234567890abcdefghij -1234567890abcdefg -1234567890abcdefghi -1234567890 -1234567890abcdefghijklmno -1234567890abcdefghij -1234567890abcdefghijklmn -1234567890abcde -1234567890abc -123456789 -1234567890abcdefgh -1234567890abcdefghij -1234567890abcdefghijklmnopqrstuvwx -1234567890abcdefghijklmnopqr -1234567890abcdefghijklmnopqrst -1234567890abcdefghijklmnopqrs -1234567890abcdefghijklmnopqrstuvwxyz -1234567890abcdefghijkl -1234 -12 -12 -12345678 -1234567 -1234567890 -123 -1234567890abc -1234567890abcdefghijklmnopqr -12 -1234567890abcde -1234567890abcdef -1234567890a -1234567890ab -1234567890abcdefghijk -1234567890abcdefghijklmnopqrstu -1234567890abcdefghijklmnop -1234567890abcdefghijk -1234567890abcdefghijklmnopqrstu -1234567890abcdefghijklmnopqrstuvw -1234567890abc diff --git a/lib/x1000-installer/test/data/lines_sorted.txt b/lib/x1000-installer/test/data/lines_sorted.txt deleted file mode 100644 index 4944efd614..0000000000 --- a/lib/x1000-installer/test/data/lines_sorted.txt +++ /dev/null @@ -1,36 +0,0 @@ -1 -12 -123 -1234 -12345 -123456 -1234567 -12345678 -123456789 -1234567890 -1234567890a -1234567890ab -1234567890abc -1234567890abcd -1234567890abcde -1234567890abcdef -1234567890abcdefg -1234567890abcdefgh -1234567890abcdefghi -1234567890abcdefghij -1234567890abcdefghijk -1234567890abcdefghijkl -1234567890abcdefghijklm -1234567890abcdefghijklmn -1234567890abcdefghijklmno -1234567890abcdefghijklmnop -1234567890abcdefghijklmnopq -1234567890abcdefghijklmnopqr -1234567890abcdefghijklmnopqrs -1234567890abcdefghijklmnopqrst -1234567890abcdefghijklmnopqrstu -1234567890abcdefghijklmnopqrstuv -1234567890abcdefghijklmnopqrstuvw -1234567890abcdefghijklmnopqrstuvwx -1234567890abcdefghijklmnopqrstuvwxy -1234567890abcdefghijklmnopqrstuvwxyz diff --git a/lib/x1000-installer/test/main.c b/lib/x1000-installer/test/main.c deleted file mode 100644 index f9bff1b704..0000000000 --- a/lib/x1000-installer/test/main.c +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include - -static int test_num_executed = 0; -static int test_num_failed = 0; -int test_num_asserts_executed = 0; -int test_num_asserts_failed = 0; - -void test_failure(const char* file, int line, const char* msg) -{ - fprintf(stderr, "%s:%d: ASSERTION FAILED: %s\n", file, line, msg); - ++test_num_asserts_failed; -} - -typedef void(*test_t)(void); - -struct test_info { - const char* name; - test_t func; -}; - -extern void test_stream_read_lines(void); -extern void test_stream_read_line_too_long(void); -extern void test_flashmap_parseline(void); - -#define TEST(x) {#x, x} -static const struct test_info all_tests[] = { - TEST(test_stream_read_lines), - TEST(test_stream_read_line_too_long), - TEST(test_flashmap_parseline), -}; -#undef TEST - -void run_test(const struct test_info* tinfo) -{ - int asserts_now = test_num_asserts_failed; - ++test_num_executed; - - fprintf(stderr, "RUN %s\n", tinfo->name); - tinfo->func(); - - if(test_num_asserts_failed > asserts_now) { - fprintf(stderr, " %s: FAILED!\n", tinfo->name); - ++test_num_failed; - } -} - -int main(int argc, char* argv[]) -{ - (void)argc; - (void)argv; - - size_t num_tests = sizeof(all_tests) / sizeof(struct test_info); - for(size_t i = 0; i < num_tests; ++i) - run_test(&all_tests[i]); - - fprintf(stderr, "------------------------------------------\n"); - fprintf(stderr, "TEST COMPLETE\n"); - fprintf(stderr, " Tests %d failed / %d executed\n", - test_num_failed, test_num_executed); - fprintf(stderr, " Assertions %d failed / %d executed\n", - test_num_asserts_failed, test_num_asserts_executed); - - if(test_num_failed > 0) - return 1; -} diff --git a/lib/x1000-installer/test/test.h b/lib/x1000-installer/test/test.h deleted file mode 100644 index 3d47a19d87..0000000000 --- a/lib/x1000-installer/test/test.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef TEST_H -#define TEST_H - -extern int test_num_asserts_executed; -extern int test_num_asserts_failed; - -extern void test_failure(const char* file, int line, const char* msg); - -#define T_ASSERT(cond) \ - do { \ - ++test_num_asserts_executed; \ - if(!(cond)) { \ - test_failure(__FILE__, __LINE__, #cond); \ - goto cleanup; \ - } \ - } while(0) - -#endif diff --git a/lib/x1000-installer/test/test_flashmap.c b/lib/x1000-installer/test/test_flashmap.c deleted file mode 100644 index 5e7aa39d78..0000000000 --- a/lib/x1000-installer/test/test_flashmap.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "test.h" -#include "xf_stream.h" -#include "xf_flashmap.h" -#include "xf_error.h" -#include "file.h" -#include -#include -#include - -#define MD5SUM \ - "abcdef012345ABCDEF012345abcdef01" -#define MD5SUM_L \ - "abcdef012345abcdef012345abcdef01" -#define LONG_NAME \ - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" -#define OVERLONG_NAME \ - LONG_NAME "a" - -static const struct parseline_test { - const char* line; - int rc; - const char* name; - const char* md5; - uint32_t file_length; - uint32_t offset; - uint32_t length; - int flags; -} parseline_tests[] = { - {"test1 " MD5SUM " 1234 0x9876 42", - XF_E_SUCCESS, "test1", MD5SUM_L, 1234, 0x9876, 42, - XF_MAP_HAS_FILE_LENGTH|XF_MAP_HAS_MD5}, - {" test1 " MD5SUM " 1234 0x9876 42", - XF_E_SUCCESS, "test1", MD5SUM_L, 1234, 0x9876, 42, - XF_MAP_HAS_FILE_LENGTH|XF_MAP_HAS_MD5}, - {"test1 " MD5SUM " 1234 0x9876 42 \r", - XF_E_SUCCESS, "test1", MD5SUM_L, 1234, 0x9876, 42, - XF_MAP_HAS_FILE_LENGTH|XF_MAP_HAS_MD5}, - {"test1 " MD5SUM " 1234 0x9876 42 # junk", - XF_E_SYNTAX_ERROR, NULL, NULL, 0, 0, 0, 0}, - {OVERLONG_NAME, - XF_E_FILENAME_TOO_LONG, NULL, NULL, 0, 0, 0, 0}, - {LONG_NAME " " MD5SUM " 1234 0x9876 42", - XF_E_SUCCESS, LONG_NAME, MD5SUM_L, 1234, 0x9876, 42, - XF_MAP_HAS_FILE_LENGTH|XF_MAP_HAS_MD5}, - {"test1 " MD5SUM " 4294967295 0 0xffffffff", - XF_E_SUCCESS, "test1", MD5SUM_L, 4294967295, 0, 0xfffffffful, - XF_MAP_HAS_FILE_LENGTH|XF_MAP_HAS_MD5}, - {"test1 " MD5SUM " 4294967295 1 0xffffffff", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM " 4294967296 0 0xffffffff", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM " 100294967295 0 0xffffffff", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM " 0 0 0xffffffff0", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM " 0 0 0x100000000", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM " 0 0 0x100000001", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"<", - XF_E_SYNTAX_ERROR, NULL, NULL, 0, 0, 0, 0}, - {"test1 abcXdef", - XF_E_SYNTAX_ERROR, NULL, NULL, 0, 0, 0, 0}, - {"test1 " MD5SUM "0", - XF_E_SYNTAX_ERROR, NULL, NULL, 0, 0, 0, 0}, - {"test1 - 4567 0xabcd", - XF_E_SUCCESS, "test1", NULL, 0, 4567, 0xabcd, 0}, - {"test1 - 0 0x123456789", - XF_E_INT_OVERFLOW, NULL, NULL, 0, 0, 0, 0}, - {"test1 - 4f", - XF_E_SYNTAX_ERROR, NULL, NULL, 0, 0, 0, 0}, -}; - -static void md5_to_string(char* buf, const uint8_t* md5) -{ - const char* hex = "0123456789abcdef"; - for(int i = 0; i < 16; ++i) { - uint8_t byte = md5[i]; - buf[2*i] = hex[(byte >> 4) & 0xf]; - buf[2*i+1] = hex[byte & 0xf]; - } - - buf[32] = '\0'; -} - -int test_flashmap_parseline(void) -{ - int rc; - struct xf_map map; - char md5string[33]; - - size_t num_cases = sizeof(parseline_tests) / sizeof(struct parseline_test); - const struct parseline_test* test = &parseline_tests[0]; - - for(; num_cases > 0; --num_cases, ++test) { - rc = xf_map_parseline(test->line, &map); - - T_ASSERT(rc == test->rc); - if(rc != XF_E_SUCCESS) - continue; - - T_ASSERT(strcmp(map.name, test->name) == 0); - T_ASSERT(map.offset == test->offset); - T_ASSERT(map.length == test->length); - T_ASSERT(map.flags == test->flags); - - if(test->flags & XF_MAP_HAS_MD5) { - md5_to_string(md5string, map.md5); - T_ASSERT(strcmp(md5string, test->md5) == 0); - } - - if(test->flags & XF_MAP_HAS_FILE_LENGTH) { - T_ASSERT(map.file_length == test->file_length); - } - } - - cleanup: - return rc; -} diff --git a/lib/x1000-installer/test/test_stream.c b/lib/x1000-installer/test/test_stream.c deleted file mode 100644 index b4a5723b76..0000000000 --- a/lib/x1000-installer/test/test_stream.c +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "test.h" -#include "xf_stream.h" -#include "xf_error.h" -#include "file.h" -#include -#include -#include - -#define TESTDATADIR "test/data/" -#define TESTFILE_SHUFFLED TESTDATADIR "lines_shuffled.txt" -#define TESTFILE_SORTED TESTDATADIR "lines_sorted.txt" - -const char line_string[] = "1234567890abcdefghijklmnopqrstuvwxyz"; - -static int read_line_cb(int n, char* buf, void* arg) -{ - int* max_n = (int*)arg; - *max_n = n; - - T_ASSERT(strlen(buf) > 0); - T_ASSERT(strncmp(line_string, buf, strlen(buf)) == 0); - - cleanup: - return 0; -} - -void test_stream_read_lines(void) -{ - struct xf_stream s; - int rc; - char buf[100]; - bool s_open = false; - - for(int bufsz = 38; bufsz <= 100; bufsz += 1) { - rc = xf_open_file(TESTFILE_SHUFFLED, O_RDONLY, &s); - T_ASSERT(rc == 0); - s_open = true; - - int max_n = 0; - rc = xf_stream_read_lines(&s, buf, bufsz, &read_line_cb, &max_n); - T_ASSERT(rc == 0); - T_ASSERT(max_n+1 == 108); - - xf_stream_close(&s); - s_open = false; - } - - cleanup: - if(s_open) - xf_stream_close(&s); - return; -} - -void test_stream_read_line_too_long(void) -{ - struct xf_stream s; - int rc; - char buf[38]; - bool s_open = false; - - for(int bufsz = 0; bufsz <= 38; bufsz += 1) { - rc = xf_open_file(TESTFILE_SORTED, O_RDONLY, &s); - T_ASSERT(rc == 0); - s_open = true; - - int max_n = -1; - rc = xf_stream_read_lines(&s, buf, bufsz, &read_line_cb, &max_n); - if(bufsz == 38) { - T_ASSERT(rc == 0); - T_ASSERT(max_n+1 == 36); - } else { - T_ASSERT(rc == XF_E_LINE_TOO_LONG); - if(bufsz <= 1) - T_ASSERT(max_n == -1); - else - T_ASSERT(max_n+1 == bufsz-2); - } - - xf_stream_close(&s); - s_open = false; - } - - cleanup: - if(s_open) - xf_stream_close(&s); - return; -} diff --git a/lib/x1000-installer/test_lib/core_alloc.c b/lib/x1000-installer/test_lib/core_alloc.c deleted file mode 100644 index 719670f8f2..0000000000 --- a/lib/x1000-installer/test_lib/core_alloc.c +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "core_alloc.h" -#include - -#define N_POINTERS 100 - -static void* pointers[N_POINTERS]; -struct buflib_callbacks buflib_ops_locked = {NULL, NULL, NULL}; - -int core_alloc(const char* name, size_t size) -{ - (void)name; - - void* mem = malloc(size); - if(!mem) - return -1; - - for(int i = 0; i < N_POINTERS; ++i) { - if(pointers[i]) - continue; - - pointers[i] = mem; - return i + 1; - } - - free(mem); - return -1; -} - -int core_alloc_ex(const char* name, size_t size, struct buflib_callbacks* cb) -{ - (void)cb; - return core_alloc(name, size); -} - -int core_free(int handle) -{ - if(handle > 0) { - free(pointers[handle-1]); - pointers[handle-1] = NULL; - } - - return 0; -} - -void* core_get_data(int handle) -{ - if(handle > 0) - return pointers[handle-1]; - - return NULL; -} diff --git a/lib/x1000-installer/test_lib/core_alloc.h b/lib/x1000-installer/test_lib/core_alloc.h deleted file mode 100644 index 2c77e3c274..0000000000 --- a/lib/x1000-installer/test_lib/core_alloc.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* fake core_alloc implementation for testing */ - -#ifndef CORE_ALLOC_H -#define CORE_ALLOC_H - -#include -#include - -struct buflib_callbacks { - int (*move_callback)(int handle, void* current, void* new); - int (*shrink_callback)(int handle, unsigned hints, void* start, size_t old_size); - void (*sync_callback)(int handle, bool sync_on); -}; - -extern struct buflib_callbacks buflib_ops_locked; - -int core_alloc(const char* name, size_t size); -int core_alloc_ex(const char* name, size_t size, struct buflib_callbacks* cb); -int core_free(int handle); -void* core_get_data(int handle); - -#endif diff --git a/lib/x1000-installer/test_lib/fakenand.c b/lib/x1000-installer/test_lib/fakenand.c deleted file mode 100644 index 19f1f31cfd..0000000000 --- a/lib/x1000-installer/test_lib/fakenand.c +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "nand-x1000.h" -#include -#include -#include -#include -#include - -const char* nand_backing_file = "fakeNAND.bin"; -const char* nand_meta_file = "fakeNAND_meta.bin"; - -struct nand_trace* nand_trace = NULL; -size_t nand_trace_capacity = 0; -size_t nand_trace_length = 0; - -static struct nand_trace* nand_trace_cur = NULL; - -static int injected_err = 0; - -#define METAF_PROGRAMMED 1 - -static const nand_chip fake_chip = { - /* ATO25D1GA */ - .log2_ppb = 6, /* 64 pages */ - .page_size = 2048, - .oob_size = 64, - .nr_blocks = 1024, -}; - -void nand_trace_reset(size_t size) -{ - nand_trace = realloc(nand_trace, size); - nand_trace_capacity = size; - nand_trace_length = 0; - nand_trace_cur = nand_trace; -} - -void nand_inject_error(int rc) -{ - injected_err = rc; -} - -nand_drv* nand_init(void) -{ - static bool inited = false; - static uint8_t scratch_buf[NAND_DRV_SCRATCHSIZE]; - static uint8_t page_buf[NAND_DRV_MAXPAGESIZE]; - static nand_drv d; - - if(!inited) { - d.scratch_buf = scratch_buf; - d.page_buf = page_buf; - d.chip = &fake_chip; - inited = true; - } - - return &d; -} - -static void lock_assert(bool cond, const char* msg) -{ - if(!cond) { - fprintf(stderr, "%s\n", msg); - fflush(stderr); - abort(); - } -} - -void nand_lock(nand_drv* drv) -{ - drv->lock_count++; -} - -void nand_unlock(nand_drv* drv) -{ - lock_assert(drv->lock_count > 0, "nand_unlock() called when not locked"); - drv->lock_count--; -} - -#define CHECK_INJECTED_ERROR \ - do { int __err = injected_err; injected_err = 0; if(__err) return __err; } while(0) - -int nand_open(nand_drv* drv) -{ - lock_assert(drv->lock_count > 0, "nand_open(): lock not held"); - CHECK_INJECTED_ERROR; - - if(drv->refcount > 0) { - drv->refcount++; - return NAND_SUCCESS; - } - - /* leaks an fd on error but this is only testing... */ - drv->fd = open(nand_backing_file, O_RDWR|O_CREAT, 0644); - drv->metafd = open(nand_meta_file, O_RDWR|O_CREAT, 0644); - if(drv->fd < 0 || drv->metafd < 0) - goto err; - - drv->ppb = 1 << drv->chip->log2_ppb; - drv->fpage_size = drv->chip->page_size + drv->chip->oob_size; - - /* make backing file the correct size */ - if(ftruncate(drv->fd, drv->chip->page_size * drv->ppb * drv->chip->nr_blocks) < 0) - goto err; - if(ftruncate(drv->metafd, drv->chip->nr_blocks * drv->ppb) < 0) - goto err; - - drv->refcount++; - return NAND_SUCCESS; - - err: - if(drv->fd >= 0) - close(drv->fd); - if(drv->metafd >= 0) - close(drv->metafd); - return NAND_ERR_OTHER; -} - -void nand_close(nand_drv* drv) -{ - lock_assert(drv->lock_count > 0, "nand_close(): lock not held"); - - if(--drv->refcount > 0) - return; - - close(drv->fd); - close(drv->metafd); - drv->fd = -1; - drv->metafd = -1; -} - -static int read_meta(nand_drv* drv, nand_page_t page) -{ - /* probably won't fail */ - if(lseek(drv->metafd, page, SEEK_SET) < 0) - return NAND_ERR_OTHER; - if(read(drv->metafd, drv->scratch_buf, 1) != 1) - return NAND_ERR_OTHER; - - return drv->scratch_buf[0]; -} - -static int write_meta(nand_drv* drv, nand_page_t page, int val) -{ - drv->scratch_buf[0] = val; - - if(lseek(drv->metafd, page, SEEK_SET) < 0) - return NAND_ERR_OTHER; - if(write(drv->metafd, drv->scratch_buf, 1) != 1) - return NAND_ERR_OTHER; - - return NAND_SUCCESS; -} - -static int upd_meta(nand_drv* drv, nand_page_t page, uint8_t clr, uint8_t set) -{ - int meta = read_meta(drv, page); - if(meta < 0) - return meta; - - meta &= ~clr; - meta |= set; - - return write_meta(drv, page, meta); -} - -static int page_program(nand_drv* drv, nand_page_t page, const void* buffer, - uint8_t clr, uint8_t set) -{ - if(lseek(drv->fd, page * drv->chip->page_size, SEEK_SET) < 0) - return NAND_ERR_OTHER; - if(write(drv->fd, buffer, drv->chip->page_size) != (ssize_t)drv->chip->page_size) - return NAND_ERR_PROGRAM_FAIL; - - return upd_meta(drv, page, clr, set); -} - -static void trace(enum nand_trace_type ty, enum nand_trace_exception ex, nand_page_t addr) -{ - if(nand_trace_length < nand_trace_capacity) { - nand_trace_cur->type = ty; - nand_trace_cur->exception = ex; - nand_trace_cur->addr = addr; - nand_trace_cur++; - nand_trace_length++; - } -} - -int nand_block_erase(nand_drv* drv, nand_block_t block) -{ - lock_assert(drv->lock_count > 0, "nand_block_erase(): lock not held"); - CHECK_INJECTED_ERROR; - - trace(NTT_ERASE, NTE_NONE, block); - - memset(drv->page_buf, 0xff, drv->fpage_size); - - for(unsigned i = 0; i < drv->ppb; ++i) { - int rc = page_program(drv, block + i, drv->page_buf, METAF_PROGRAMMED, 0); - if(rc < 0) - return NAND_ERR_ERASE_FAIL; - } - - return NAND_SUCCESS; -} - -int nand_page_program(nand_drv* drv, nand_page_t page, const void* buffer) -{ - lock_assert(drv->lock_count > 0, "nand_page_program(): lock not held"); - CHECK_INJECTED_ERROR; - - int meta = read_meta(drv, page); - if(meta < 0) - return meta; - - enum nand_trace_exception exception = NTE_NONE; - if(meta & METAF_PROGRAMMED) - exception = NTE_DOUBLE_PROGRAMMED; - - trace(NTT_PROGRAM, exception, page); - - return page_program(drv, page, buffer, 0, METAF_PROGRAMMED); -} - -int nand_page_read(nand_drv* drv, nand_page_t page, void* buffer) -{ - lock_assert(drv->lock_count > 0, "nand_page_read(): lock not held"); - CHECK_INJECTED_ERROR; - - enum nand_trace_exception exception = NTE_NONE; - - int meta = read_meta(drv, page); - if(meta < 0) - return meta; - - if(meta & METAF_PROGRAMMED) { - if(lseek(drv->fd, page * drv->chip->page_size, SEEK_SET) < 0) - return NAND_ERR_OTHER; - if(read(drv->fd, buffer, drv->chip->page_size) != (ssize_t)drv->chip->page_size) - return NAND_ERR_OTHER; - } else { - memset(buffer, 0xff, drv->chip->page_size); - exception = NTE_CLEARED; - } - - trace(NTT_READ, exception, page); - - memset(buffer + drv->chip->page_size, 0xff, drv->chip->oob_size); - return NAND_SUCCESS; -} diff --git a/lib/x1000-installer/test_lib/file.c b/lib/x1000-installer/test_lib/file.c deleted file mode 100644 index 8769c009a4..0000000000 --- a/lib/x1000-installer/test_lib/file.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "file.h" - -off_t filesize(int osfd) -{ - struct stat sb; - - if (!fstat(osfd, &sb)) - return sb.st_size; - else - return -1; -} diff --git a/lib/x1000-installer/test_lib/file.h b/lib/x1000-installer/test_lib/file.h deleted file mode 100644 index 2a6554c695..0000000000 --- a/lib/x1000-installer/test_lib/file.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FILE_H -#define FILE_H - -#include -#include -#include -#include -#include - -#ifdef MAX_PATH -# undef MAX_PATH -#endif - -#define MAX_PATH 260 - -off_t filesize(int fd); - -#endif diff --git a/lib/x1000-installer/test_lib/md5.c b/lib/x1000-installer/test_lib/md5.c deleted file mode 100644 index 3050c7ebd8..0000000000 --- a/lib/x1000-installer/test_lib/md5.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Copyright (C) 2001-2003 Christophe Devine - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#include "md5.h" - -#define GET_UINT32(n,b,i) \ -{ \ - (n) = ( (uint32_t) (b)[(i) ] ) \ - | ( (uint32_t) (b)[(i) + 1] << 8 ) \ - | ( (uint32_t) (b)[(i) + 2] << 16 ) \ - | ( (uint32_t) (b)[(i) + 3] << 24 ); \ -} - -#define PUT_UINT32(n,b,i) \ -{ \ - (b)[(i) ] = (uint8_t) ( (n) ); \ - (b)[(i) + 1] = (uint8_t) ( (n) >> 8 ); \ - (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \ - (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ -} - -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md5_process( md5_context *ctx, uint8_t data[64] ) -{ - uint32_t X[16], A, B, C, D; - - GET_UINT32( X[0], data, 0 ); - GET_UINT32( X[1], data, 4 ); - GET_UINT32( X[2], data, 8 ); - GET_UINT32( X[3], data, 12 ); - GET_UINT32( X[4], data, 16 ); - GET_UINT32( X[5], data, 20 ); - GET_UINT32( X[6], data, 24 ); - GET_UINT32( X[7], data, 28 ); - GET_UINT32( X[8], data, 32 ); - GET_UINT32( X[9], data, 36 ); - GET_UINT32( X[10], data, 40 ); - GET_UINT32( X[11], data, 44 ); - GET_UINT32( X[12], data, 48 ); - GET_UINT32( X[13], data, 52 ); - GET_UINT32( X[14], data, 56 ); - GET_UINT32( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -void md5_update( md5_context *ctx, uint8_t *input, uint32_t length ) -{ - uint32_t left, fill; - - if( ! length ) return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += length; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < length ) - ctx->total[1]++; - - if( left && length >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - md5_process( ctx, ctx->buffer ); - length -= fill; - input += fill; - left = 0; - } - - while( length >= 64 ) - { - md5_process( ctx, input ); - length -= 64; - input += 64; - } - - if( length ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, length ); - } -} - -static uint8_t md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void md5_finish( md5_context *ctx, uint8_t digest[16] ) -{ - uint32_t last, padn; - uint32_t high, low; - uint8_t msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32( low, msglen, 0 ); - PUT_UINT32( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_UINT32( ctx->state[0], digest, 0 ); - PUT_UINT32( ctx->state[1], digest, 4 ); - PUT_UINT32( ctx->state[2], digest, 8 ); - PUT_UINT32( ctx->state[3], digest, 12 ); -} diff --git a/lib/x1000-installer/test_lib/md5.h b/lib/x1000-installer/test_lib/md5.h deleted file mode 100644 index 882636ed9a..0000000000 --- a/lib/x1000-installer/test_lib/md5.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _MD5_H -#define _MD5_H - -#include - -typedef struct -{ - uint32_t total[2]; - uint32_t state[4]; - uint8_t buffer[64]; -} -md5_context; - -void md5_starts( md5_context *ctx ); -void md5_update( md5_context *ctx, uint8_t *input, uint32_t length ); -void md5_finish( md5_context *ctx, uint8_t digest[16] ); - -#endif /* md5.h */ diff --git a/lib/x1000-installer/test_lib/nand-x1000.h b/lib/x1000-installer/test_lib/nand-x1000.h deleted file mode 100644 index f34f2ce026..0000000000 --- a/lib/x1000-installer/test_lib/nand-x1000.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2021 Aidan MacDonald - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -/* Stripped down fake version of X1000 NAND API for testing purposes, - * uses a normal file to store the data */ - -#ifndef __NAND_X1000_H__ -#define __NAND_X1000_H__ - -#include -#include -#include - -#define NAND_SUCCESS 0 -#define NAND_ERR_UNKNOWN_CHIP (-1) -#define NAND_ERR_PROGRAM_FAIL (-2) -#define NAND_ERR_ERASE_FAIL (-3) -#define NAND_ERR_UNALIGNED (-4) -#define NAND_ERR_OTHER (-5) -#define NAND_ERR_INJECTED (-6) - -/* keep max page size in sync with the NAND chip table in the .c file */ -#define NAND_DRV_SCRATCHSIZE 32 -#define NAND_DRV_MAXPAGESIZE 2112 - -typedef uint32_t nand_block_t; -typedef uint32_t nand_page_t; - -enum nand_trace_type { - NTT_READ, - NTT_PROGRAM, - NTT_ERASE, -}; - -enum nand_trace_exception { - NTE_NONE, - NTE_DOUBLE_PROGRAMMED, - NTE_CLEARED, -}; - -struct nand_trace { - enum nand_trace_type type; - enum nand_trace_exception exception; - nand_page_t addr; -}; - -typedef struct nand_chip { - /* Base2 logarithm of the number of pages per block */ - unsigned log2_ppb; - - /* Size of a page's main / oob areas, in bytes. */ - unsigned page_size; - unsigned oob_size; - - /* Total number of blocks in the chip */ - unsigned nr_blocks; -} nand_chip; - -typedef struct nand_drv { - /* Backing file */ - int fd; - int metafd; - int lock_count; - - unsigned refcount; - uint8_t* scratch_buf; - uint8_t* page_buf; - const nand_chip* chip; - unsigned ppb; - unsigned fpage_size; -} nand_drv; - -extern const char* nand_backing_file; -extern const char* nand_meta_file; - -extern struct nand_trace* nand_trace; -extern size_t nand_trace_capacity; -extern size_t nand_trace_length; - -extern void nand_trace_reset(size_t size); -extern void nand_inject_error(int rc); - -extern nand_drv* nand_init(void); - -extern void nand_lock(nand_drv* drv); -extern void nand_unlock(nand_drv* drv); - -extern int nand_open(nand_drv* drv); -extern void nand_close(nand_drv* drv); -extern int nand_block_erase(nand_drv* drv, nand_block_t block); -extern int nand_page_program(nand_drv* drv, nand_page_t page, const void* buffer); -extern int nand_page_read(nand_drv* drv, nand_page_t page, void* buffer); - -#endif /* __NAND_X1000_H__ */ diff --git a/lib/x1000-installer/test_lib/pathfuncs.c b/lib/x1000-installer/test_lib/pathfuncs.c deleted file mode 100644 index 341efd4730..0000000000 --- a/lib/x1000-installer/test_lib/pathfuncs.c +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2014 by Michael Sevakis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "pathfuncs.h" -#include "strlcpy.h" -#include "system.h" -#include - -static const char* GOBBLE_PATH_SEPCH(const char* p) -{ - int c; - while((c = *p) == PATH_SEPCH) - ++p; - return p; -} - -static const char* GOBBLE_PATH_COMP(const char* p) -{ - int c; - while((c = *p) && c != PATH_SEPCH) - ++p; - return p; -} - -/* Strips the trailing component from the path - * "" *nameptr->NUL, len=0: "" - * "/" *nameptr->/, len=1: "/" - * "//" *nameptr->2nd /, len=1: "/" - * "/a" *nameptr->/, len=1: "/" - * "a/" *nameptr->a, len=0: "" - * "/a/bc" *nameptr->/, len=2: "/a" - * "d" *nameptr->d, len=0: "" - * "ef/gh" *nameptr->e, len=2: "ef" - * - * Notes: * Interpret len=0 as ".". - * * In the same string, path_dirname() returns a pointer with the - * same or lower address as path_basename(). - * * Pasting a separator between the returns of path_dirname() and - * path_basename() will result in a path equivalent to the input. - * - */ -size_t path_dirname(const char *name, const char **nameptr) -{ - const char *p = GOBBLE_PATH_SEPCH(name); - const char *q = name; - const char *r = p; - - while (*(p = GOBBLE_PATH_COMP(p))) - { - const char *s = p; - - if (!*(p = GOBBLE_PATH_SEPCH(p))) - break; - - q = s; - } - - if (q == name && r > name) - name = r, q = name--; /* root - return last slash */ - - *nameptr = name; - return q - name; -} - -/* Appends one path to another, adding separators between components if needed. - * Return value and behavior is otherwise as strlcpy so that truncation may be - * detected. - * - * For basepath and component: - * PA_SEP_HARD adds a separator even if the base path is empty - * PA_SEP_SOFT adds a separator only if the base path is not empty - */ -size_t path_append(char *buf, const char *basepath, - const char *component, size_t bufsize) -{ - const char *base = basepath && basepath[0] ? basepath : buf; - if (!base) - return bufsize; /* won't work to get lengths from buf */ - - if (!buf) - bufsize = 0; - - if (path_is_absolute(component)) - { - /* 'component' is absolute; replace all */ - basepath = component; - component = ""; - } - - /* if basepath is not null or empty, buffer contents are replaced, - otherwise buf contains the base path */ - size_t len = base == buf ? strlen(buf) : my_strlcpy(buf, basepath, bufsize); - - bool separate = false; - - if (!basepath || !component) - separate = !len || base[len-1] != PATH_SEPCH; - else if (component[0]) - separate = len && base[len-1] != PATH_SEPCH; - - /* caller might lie about size of buf yet use buf as the base */ - if (base == buf && bufsize && len >= bufsize) - buf[bufsize - 1] = '\0'; - - buf += len; - bufsize -= MIN(len, bufsize); - - if (separate && (len++, bufsize > 0) && --bufsize > 0) - *buf++ = PATH_SEPCH; - - return len + my_strlcpy(buf, component ?: "", bufsize); -} diff --git a/lib/x1000-installer/test_lib/pathfuncs.h b/lib/x1000-installer/test_lib/pathfuncs.h deleted file mode 100644 index 225b3cdd19..0000000000 --- a/lib/x1000-installer/test_lib/pathfuncs.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2014 by Michael Sevakis - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef _PATHFUNCS_H_ -#define _PATHFUNCS_H_ - -#include -#include - -#define PATH_SEPCH '/' - -/* return true if path begins with a root '/' component and is not NULL */ -static inline bool path_is_absolute(const char *path) -{ - return path && path[0] == PATH_SEPCH; -} - -size_t path_dirname(const char *name, const char **nameptr); -size_t path_append(char *buf, const char *basepath, - const char *component, size_t bufsize); - -#endif diff --git a/lib/x1000-installer/test_lib/strlcpy.c b/lib/x1000-installer/test_lib/strlcpy.c deleted file mode 100644 index 681d917503..0000000000 --- a/lib/x1000-installer/test_lib/strlcpy.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ - -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -my_strlcpy(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} diff --git a/lib/x1000-installer/test_lib/strlcpy.h b/lib/x1000-installer/test_lib/strlcpy.h deleted file mode 100644 index 0c4b16dd5a..0000000000 --- a/lib/x1000-installer/test_lib/strlcpy.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef STRLCPY_H -#define STRLCPY_H -size_t my_strlcpy(char *dst, const char *src, size_t siz); -#endif diff --git a/lib/x1000-installer/test_lib/system.h b/lib/x1000-installer/test_lib/system.h deleted file mode 100644 index b0a5076ba9..0000000000 --- a/lib/x1000-installer/test_lib/system.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SYSTEM_H -#define SYSTEM_H - -#define CACHEALIGN_SIZE 1 -#define CACHEALIGN_BUFFER(x,y) do { } while(0) -#define MIN(a, b) (((a)<(b))?(a):(b)) -#define ALIGN_BUFFER(ptr, size, align) do { } while(0) -#define ALIGN_UP_P2(x, p) (((x) + ((1 << (p)) - 1)) & ~((1 << (p)) - 1)) - -#endif diff --git a/lib/x1000-installer/x1000-installer.make b/lib/x1000-installer/x1000-installer.make deleted file mode 100644 index d58bd2042f..0000000000 --- a/lib/x1000-installer/x1000-installer.make +++ /dev/null @@ -1,21 +0,0 @@ -# __________ __ ___. -# Open \______ \ ____ ____ | | _\_ |__ _______ ___ -# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -# \/ \/ \/ \/ \/ -# - -X1000INSTALLER_DIR = $(ROOTDIR)/lib/x1000-installer -X1000INSTALLER_SRC = $(call preprocess, $(X1000INSTALLER_DIR)/SOURCES) -X1000INSTALLER_OBJ := $(call c2obj, $(X1000INSTALLER_SRC)) - -X1000INSTALLERLIB = $(BUILDDIR)/lib/libx1000-installer.a - -INCLUDES += -I$(X1000INSTALLER_DIR)/include -OTHER_SRC += $(X1000INSTALLER_SRC) -CORE_LIBS += $(X1000INSTALLERLIB) - -$(X1000INSTALLERLIB): $(X1000INSTALLER_OBJ) - $(SILENT)$(shell rm -f $@) - $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null