From ba010851fafea3da0d0655b103158f0a9efe6406 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Mon, 19 Dec 2022 21:46:52 +0000 Subject: 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/src/xf_nandio.c | 292 ------------------------------------ 1 file changed, 292 deletions(-) delete mode 100644 lib/x1000-installer/src/xf_nandio.c (limited to 'lib/x1000-installer/src/xf_nandio.c') 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; -} -- cgit v1.2.3