diff --git a/u-boot/common/Makefile b/u-boot/common/Makefile index e3529407f7..22ee637c0e 100644 --- a/u-boot/common/Makefile +++ b/u-boot/common/Makefile @@ -60,7 +60,7 @@ COBJS = main.o circbuf.o \ cmd_nand.o cmd_net.o cmd_nvedit.o \ cmd_pci.o cmd_pcmcia.o cmd_portio.o \ cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_universe.o \ - cmd_usb.o cmd_vfd.o cmd_ethreg.o cmd_recovery.o \ + cmd_usb.o cmd_vfd.o cmd_ethreg.o cmd_recovery.o cmd_bootcycle.o \ command.o console.o devices.o dlmalloc.o \ environment.o env_common.o \ env_nand.o env_dataflash.o env_flash.o env_eeprom.o \ diff --git a/u-boot/common/cmd_bootcycle.c b/u-boot/common/cmd_bootcycle.c new file mode 100644 index 0000000000..368afc081b --- /dev/null +++ b/u-boot/common/cmd_bootcycle.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2015 + * Alexander Couzens, lynxis@fe80.eu + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + +#ifdef CFG_CMD_BOOTCYCLE + +#ifndef MAX_REBOOTS +#define MAX_REBOOTS 10 +#endif + +#define SRAM_BOOT_CYCLE 0xbd000100 + +#define BOOT_CYCLE_MAGIC 0xfeedb00d +#define BOOT_CYCLE_VERSION 1 + +struct sram_boot_cycle +{ + uint32_t magic; + uint32_t version; + uint32_t counter; + uint32_t crc; +}; + +static int valid_boot_cycle(struct sram_boot_cycle *sram) +{ + if (sram->magic != BOOT_CYCLE_MAGIC) + return 0; + + if (sram->version != BOOT_CYCLE_VERSION) + return 0; + + uint32_t crc = crc32(0xdeadbeef, (void *)sram, sizeof(*sram) - 4); + if (crc != sram->crc) + return 0; + + return 1; +} + +static void init_boot_cycle(struct sram_boot_cycle *sram) +{ + sram->magic = BOOT_CYCLE_MAGIC; + sram->version = BOOT_CYCLE_VERSION; + sram->counter = 0; +} + +void increase_boot_cycle(struct sram_boot_cycle *sram) +{ + if (!valid_boot_cycle(sram)) + init_boot_cycle(sram); + + sram->counter++; + sram->crc = (uint32_t) crc32(0xdeadbeef, (void *)sram, sizeof(*sram) - 4); +} + +int do_inccycle(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { + increase_boot_cycle((void *) SRAM_BOOT_CYCLE); + return CMD_RET_SUCCESS; +} + +/* report failure when we need to go to rescue */ +int do_checkcycle(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct sram_boot_cycle *sram = (void *) SRAM_BOOT_CYCLE; + /* when called we should ever have a valid boot cycle entry + * if it's invalid we have most likely a broken bootloader or hw? */ + if (!valid_boot_cycle(sram)) { + printf("Invalid boot cycle partition!\n"); + return CMD_RET_FAILURE; + } + printf("bootcycle counter: %d\n", sram->counter); + + if (sram->counter >= threshold) { + printf("Reached maximum reboot.\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + checkcycle, 1, 0, do_checkcycle, + "checkcycle - check if we need to boot rescue system\n", + NULL +); + +U_BOOT_CMD( + inccycle, 1, 0, do_inccycle, + "inccycle - increase boot cycle counter\n", + NULL +); + +#endif /* CFG_CMD_BOOTCYCLE */ diff --git a/u-boot/include/configs/carambola2.h b/u-boot/include/configs/carambola2.h index 2b22ee5bda..5441d7c565 100644 --- a/u-boot/include/configs/carambola2.h +++ b/u-boot/include/configs/carambola2.h @@ -11,6 +11,8 @@ /* enable watchdog */ #define CONFIG_HW_WATCHDOG +#define CFG_CMD_BOOTCYCLE + /*----------------------------------------------------------------------- * FLASH and environment organization *----------------------------------------------------------------------- diff --git a/u-boot/include/configs/skylab.h b/u-boot/include/configs/skylab.h index 1f0a337b77..a441776767 100644 --- a/u-boot/include/configs/skylab.h +++ b/u-boot/include/configs/skylab.h @@ -11,6 +11,8 @@ /* enable watchdog */ #define CONFIG_HW_WATCHDOG +#define CFG_CMD_BOOTCYCLE + /*----------------------------------------------------------------------- * FLASH and environment organization *-----------------------------------------------------------------------