From 3ec66893e377b088c1284d2d23adb2aeea6d7965 Mon Sep 17 00:00:00 2001 From: Aidan MacDonald Date: Sat, 27 Feb 2021 22:08:58 +0000 Subject: New port: FiiO M3K on bare metal Change-Id: I7517e7d5459e129dcfc9465c6fbd708619888fbe --- .../mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c | 195 +++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c (limited to 'firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c') diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c new file mode 100644 index 0000000000..c794da4000 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/fiiom3k/installer-fiiom3k.c @@ -0,0 +1,195 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "installer.h" +#include "nand-x1000.h" +#include "core_alloc.h" +#include "file.h" + +#define INSTALL_SUCCESS 0 +#define ERR_FLASH_OPEN_FAILED (-1) +#define ERR_FLASH_ENABLE_WP_FAILED (-2) +#define ERR_FLASH_DISABLE_WP_FAILED (-3) +#define ERR_FLASH_ERASE_FAILED (-4) +#define ERR_FLASH_WRITE_FAILED (-5) +#define ERR_FLASH_READ_FAILED (-6) +#define ERR_OUT_OF_MEMORY (-7) +#define ERR_CANNOT_READ_FILE (-8) +#define ERR_CANNOT_WRITE_FILE (-9) +#define ERR_WRONG_SIZE (-10) + +#define BOOT_IMAGE_SIZE (128 * 1024) + +static int install_from_buffer(const void* buf) +{ + if(nand_open()) + return ERR_FLASH_OPEN_FAILED; + + int status = INSTALL_SUCCESS; + + if(nand_enable_writes(true)) { + status = ERR_FLASH_DISABLE_WP_FAILED; + goto _exit; + } + + if(nand_erase_block(0)) { + status = ERR_FLASH_ERASE_FAILED; + goto _exit; + } + + if(nand_write_bytes(0, BOOT_IMAGE_SIZE, buf)) { + status = ERR_FLASH_WRITE_FAILED; + goto _exit; + } + + if(nand_enable_writes(false)) { + status = ERR_FLASH_ENABLE_WP_FAILED; + goto _exit; + } + + _exit: + nand_close(); + return status; +} + +static int dump_to_buffer(void* buf) +{ + if(nand_open()) + return ERR_FLASH_OPEN_FAILED; + + int status = INSTALL_SUCCESS; + + if(nand_read_bytes(0, BOOT_IMAGE_SIZE, buf)) { + status = ERR_FLASH_READ_FAILED; + goto _exit; + } + + _exit: + nand_close(); + return status; +} + +int install_bootloader(const char* path) +{ + /* Allocate memory to hold image */ + int handle = core_alloc("boot_image", BOOT_IMAGE_SIZE); + if(handle < 0) + return ERR_OUT_OF_MEMORY; + + int status = INSTALL_SUCCESS; + void* buffer = core_get_data(handle); + + /* Open the boot image */ + int fd = open(path, O_RDONLY); + if(fd < 0) { + status = ERR_CANNOT_READ_FILE; + goto _exit; + } + + /* Check file size */ + off_t fsize = filesize(fd); + if(fsize != BOOT_IMAGE_SIZE) { + status = ERR_WRONG_SIZE; + goto _exit; + } + + /* Read the file into the buffer */ + ssize_t cnt = read(fd, buffer, BOOT_IMAGE_SIZE); + if(cnt != BOOT_IMAGE_SIZE) { + status = ERR_CANNOT_READ_FILE; + goto _exit; + } + + /* Perform the installation */ + status = install_from_buffer(buffer); + + _exit: + if(fd >= 0) + close(fd); + core_free(handle); + return status; +} + +/* Dump the current bootloader to a file */ +int dump_bootloader(const char* path) +{ + /* Allocate memory to hold image */ + int handle = core_alloc("boot_image", BOOT_IMAGE_SIZE); + if(handle < 0) + return -1; + + /* Read data from flash */ + int fd = -1; + void* buffer = core_get_data(handle); + int status = dump_to_buffer(buffer); + if(status) + goto _exit; + + /* Open file */ + fd = open(path, O_CREAT|O_TRUNC|O_WRONLY); + if(fd < 0) { + status = ERR_CANNOT_WRITE_FILE; + goto _exit; + } + + /* Write data to file */ + ssize_t cnt = write(fd, buffer, BOOT_IMAGE_SIZE); + if(cnt != BOOT_IMAGE_SIZE) { + status = ERR_CANNOT_WRITE_FILE; + goto _exit; + } + + _exit: + if(fd >= 0) + close(fd); + core_free(handle); + return status; +} + +const char* installer_strerror(int rc) +{ + switch(rc) { + case INSTALL_SUCCESS: + return "Success"; + case ERR_FLASH_OPEN_FAILED: + return "Can't open flash device"; + case ERR_FLASH_ENABLE_WP_FAILED: + return "Couldn't re-enable write protect"; + case ERR_FLASH_DISABLE_WP_FAILED: + return "Can't disable write protect"; + case ERR_FLASH_ERASE_FAILED: + return "Flash erase failed"; + case ERR_FLASH_WRITE_FAILED: + return "Flash write error"; + case ERR_FLASH_READ_FAILED: + return "Flash read error"; + case ERR_OUT_OF_MEMORY: + return "Out of memory"; + case ERR_CANNOT_READ_FILE: + return "Error reading file"; + case ERR_CANNOT_WRITE_FILE: + return "Error writing file"; + case ERR_WRONG_SIZE: + return "Wrong file size"; + default: + return "Unknown error"; + } +} -- cgit v1.2.3