diff --git a/fusee/fusee-primary/src/exception_handlers.c b/fusee/fusee-primary/src/exception_handlers.c index e8d34f702..e0e5392b0 100644 --- a/fusee/fusee-primary/src/exception_handlers.c +++ b/fusee/fusee-primary/src/exception_handlers.c @@ -17,9 +17,8 @@ #include #include "exception_handlers.h" -#include "lib/driver_utils.h" #include "utils.h" -#include "display/video_fb.h" +#include "lib/log.h" #define CODE_DUMP_SIZE 0x30 #define STACK_DUMP_SIZE 0x60 @@ -55,26 +54,28 @@ void exception_handler_main(uint32_t *registers, unsigned int exception_type) { uint32_t instr_addr = pc + ((cpsr & 0x20) ? 2 : 4) - CODE_DUMP_SIZE; - printk("\nSomething went wrong...\n"); + print(SCREEN_LOG_LEVEL_ERROR, "\nSomething went wrong...\n"); code_dump_size = safecpy(code_dump, (const void *)instr_addr, CODE_DUMP_SIZE); stack_dump_size = safecpy(stack_dump, (const void *)registers[13], STACK_DUMP_SIZE); - printk("\nException type: %s\n", exception_names[exception_type]); - printk("\nRegisters:\n\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nException type: %s\n", + exception_names[exception_type]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nRegisters:\n\n"); /* Print r0 to pc. */ for (int i = 0; i < 16; i += 2) { - printk("%-7s%08"PRIX32" %-7s%08"PRIX32"\n", register_names[i], registers[i], register_names[i+1], registers[i+1]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32" %-7s%08"PRIX32"\n", + register_names[i], registers[i], register_names[i+1], registers[i+1]); } /* Print cpsr. */ - printk("%-7s%08"PRIX32"\n", register_names[16], registers[16]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32"\n", register_names[16], registers[16]); - printk("\nCode dump:\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nCode dump:\n"); hexdump(code_dump, code_dump_size, instr_addr); - printk("\nStack dump:\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nStack dump:\n"); hexdump(stack_dump, stack_dump_size, registers[13]); - printk("\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n"); fatal_error("An exception occured!\n"); } diff --git a/fusee/fusee-primary/src/fs_utils.c b/fusee/fusee-primary/src/fs_utils.c index b81bfec6a..f788c1f94 100644 --- a/fusee/fusee-primary/src/fs_utils.c +++ b/fusee/fusee-primary/src/fs_utils.c @@ -13,11 +13,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include "fs_utils.h" #include "mc.h" -#include "lib/printk.h" #include "lib/fatfs/ff.h" +#include "lib/log.h" FATFS sd_fs; static bool g_sd_mounted = false; @@ -44,7 +44,7 @@ bool mount_sd(void) /* Mount SD. */ if (f_mount(&sd_fs, "", 1) == FR_OK) { - printk("Mounted SD card!\n"); + print(SCREEN_LOG_LEVEL_INFO, "Mounted SD card!\n"); g_sd_mounted = true; } } diff --git a/fusee/fusee-primary/src/lib/driver_utils.h b/fusee/fusee-primary/src/lib/driver_utils.h deleted file mode 100644 index b79611113..000000000 --- a/fusee/fusee-primary/src/lib/driver_utils.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#ifndef FUSEE_DRIVER_UTILS_H -#define FUSEE_DRIVER_UTILS_H - -#include "vsprintf.h" -#include "printk.h" - -#endif diff --git a/fusee/fusee-primary/src/lib/log.c b/fusee/fusee-primary/src/lib/log.c new file mode 100644 index 000000000..4aa396d72 --- /dev/null +++ b/fusee/fusee-primary/src/lib/log.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include "log.h" + +#include "../display/video_fb.h" +#include "vsprintf.h" + +/* default log level for screen output */ +ScreenLogLevel g_screen_log_level = SCREEN_LOG_LEVEL_MANDATORY; + +void log_set_log_level(ScreenLogLevel log_level) { + g_screen_log_level = log_level; +} + +void log_to_uart(const char *message) { + /* TODO: add UART logging */ +} + +void print_to_screen(ScreenLogLevel screen_log_level, char *message) { + /* don't print to screen if below log level */ + if(screen_log_level > g_screen_log_level) return; + + video_puts(message); +} + +/** + * vprintk - logs a message and prints it to screen based on its screen_log_level + * + * If the level is below g_screen_log_level it will not be shown but logged to UART + * This text will not be colored or prefixed + * UART is TODO + */ +void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args) +{ + char buf[PRINT_MESSAGE_MAX_LENGTH]; + vsnprintf(buf, PRINT_MESSAGE_MAX_LENGTH, fmt, args); + + /* we don't need that flag here, but if it gets used, strip it so we print correctly */ + screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX; + + /* log to UART */ + log_to_uart(buf); + + print_to_screen(screen_log_level, buf); +} + +void add_prefix(ScreenLogLevel screen_log_level, const char *fmt, char *buf) { + char typebuf[] = "[%s] %s"; + + /* apply prefix and append message format */ + /* TODO: add coloring to the output */ + switch(screen_log_level) + { + case SCREEN_LOG_LEVEL_ERROR: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "ERROR", fmt); + break; + case SCREEN_LOG_LEVEL_WARNING: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "WARNING", fmt); + break; + case SCREEN_LOG_LEVEL_MANDATORY: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt); + break; + case SCREEN_LOG_LEVEL_INFO: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "INFO", fmt); + break; + case SCREEN_LOG_LEVEL_DEBUG: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "DEBUG", fmt); + break; + default: + break; + } +} + +/** + * print - logs a message and prints it to screen based on its screen_log_level + * + * If the level is below g_screen_log_level it will not be shown but logged to UART + * Use SCREEN_LOG_LEVEL_NO_PREFIX if you don't want a prefix to be added + * UART is TODO + */ +void print(ScreenLogLevel screen_log_level, const char * fmt, ...) +{ + char buf[PRINT_MESSAGE_MAX_LENGTH] = {}; + char message[PRINT_MESSAGE_MAX_LENGTH] = {}; + + /* TODO: make splash disappear if level > MANDATORY */ + + /* make prefix free messages with log_level possible */ + if(screen_log_level & SCREEN_LOG_LEVEL_NO_PREFIX) { + /* remove the NO_PREFIX flag so the enum can be recognized later on */ + screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX; + + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt); + } + else { + add_prefix(screen_log_level, fmt, buf); + } + + /* input arguments */ + va_list args; + va_start(args, fmt); + vsnprintf(message, PRINT_MESSAGE_MAX_LENGTH, buf, args); + va_end(args); + + /* log to UART */ + log_to_uart(message); + + print_to_screen(screen_log_level, message); +} \ No newline at end of file diff --git a/fusee/fusee-primary/src/lib/log.h b/fusee/fusee-primary/src/lib/log.h new file mode 100644 index 000000000..00ddfdb6e --- /dev/null +++ b/fusee/fusee-primary/src/lib/log.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#ifndef FUSEE_PRIMARY_PRINT_H +#define FUSEE_PRIMARY_PRINT_H + +#define PRINT_MESSAGE_MAX_LENGTH 512 + +#include + +typedef enum { + SCREEN_LOG_LEVEL_NONE = 0, + SCREEN_LOG_LEVEL_ERROR = 1, + SCREEN_LOG_LEVEL_WARNING = 2, + SCREEN_LOG_LEVEL_MANDATORY = 3, /* no log prefix */ + SCREEN_LOG_LEVEL_INFO = 4, + SCREEN_LOG_LEVEL_DEBUG = 5, + + SCREEN_LOG_LEVEL_NO_PREFIX = 0x100 /* OR this to your LOG_LEVEL to prevent prefix creation */ +} ScreenLogLevel; + +/* TODO: make this configurable by BCT.ini */ +extern ScreenLogLevel g_screen_log_level; + +void log_set_log_level(ScreenLogLevel screen_log_level); +void log_to_uart(const char *message); +void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args); +void print(ScreenLogLevel screen_log_level, const char* fmt, ...); + +#endif \ No newline at end of file diff --git a/fusee/fusee-primary/src/lib/printk.c b/fusee/fusee-primary/src/lib/printk.c deleted file mode 100644 index 30b36ab00..000000000 --- a/fusee/fusee-primary/src/lib/printk.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#include "printk.h" - -#include "vsprintf.h" -#include "../display/video_fb.h" - -/** - * Temporary stand-in main printk. - * - * TODO: This should print via UART, console framebuffer, and to a ring for - * consumption by Horizon - */ -void printk(const char *fmt, ...) -{ - va_list list; - va_start(list, fmt); - vprintk(fmt, list); - va_end(list); -} - - -void vprintk(const char *fmt, va_list args) -{ - char buf[512]; - vsnprintf(buf, sizeof(buf), fmt, args); - video_puts(buf); -} diff --git a/fusee/fusee-primary/src/lib/printk.h b/fusee/fusee-primary/src/lib/printk.h deleted file mode 100644 index 4c63b9b6f..000000000 --- a/fusee/fusee-primary/src/lib/printk.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#ifndef __PRINTK_H__ -#define __PRINTK_H__ - -#include - -void printk(const char *fmt, ...); -void vprintk(const char *fmt, va_list args); - -#endif diff --git a/fusee/fusee-primary/src/main.c b/fusee/fusee-primary/src/main.c index fca4e5f1c..b41149ce4 100644 --- a/fusee/fusee-primary/src/main.c +++ b/fusee/fusee-primary/src/main.c @@ -25,7 +25,7 @@ #include "chainloader.h" #include "sdmmc/sdmmc.h" #include "lib/fatfs/ff.h" -#include "lib/printk.h" +#include "lib/log.h" #include "display/video_fb.h" extern void (*__program_exit_callback)(int rc); @@ -42,8 +42,8 @@ static char g_bct0_buffer[BCTO_MAX_SIZE]; static const char *load_config(void) { if (!read_from_file(g_bct0_buffer, BCTO_MAX_SIZE, "BCT.ini")) { - printk("Failed to read BCT0 from SD!\n"); - printk("[DEBUG] Using default BCT0!\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Failed to read BCT0 from SD!\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Using default BCT0!\n"); memcpy(g_bct0_buffer, DEFAULT_BCT0_FOR_DEBUG, sizeof(DEFAULT_BCT0_FOR_DEBUG)); /* TODO: Stop using default. */ /* printk("Error: Failed to load BCT.ini!\n"); @@ -119,8 +119,8 @@ int main(void) { setup_env(); /* Say hello. */ - printk("Welcome to Atmosph\xe8re Fus\xe9" "e!\n"); - printk("Using color linear framebuffer at 0x%p!\n", g_framebuffer); + print(SCREEN_LOG_LEVEL_MANDATORY, "Welcome to Atmosph\xe8re Fus\xe9" "e!\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Using color linear framebuffer at 0x%p!\n", g_framebuffer); /* Load the BCT0 configuration ini off of the SD. */ bct0 = load_config(); diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc.c b/fusee/fusee-primary/src/sdmmc/sdmmc.c index e4a59c046..3aeb59f90 100644 --- a/fusee/fusee-primary/src/sdmmc/sdmmc.c +++ b/fusee/fusee-primary/src/sdmmc/sdmmc.c @@ -26,7 +26,6 @@ #include "mmc.h" #include "sd.h" #include "../timers.h" -#include "../lib/driver_utils.h" #define UNSTUFF_BITS(resp,start,size) \ ({ \ diff --git a/fusee/fusee-primary/src/sdmmc/sdmmc_core.c b/fusee/fusee-primary/src/sdmmc/sdmmc_core.c index c831493f5..9d353d3b9 100644 --- a/fusee/fusee-primary/src/sdmmc/sdmmc_core.c +++ b/fusee/fusee-primary/src/sdmmc/sdmmc_core.c @@ -30,7 +30,7 @@ #include "../gpio.h" #include "../pmc.h" #include "../max7762x.h" -#include "../lib/driver_utils.h" +#include "../lib/log.h" static SdmmcLogLevel g_sdmmc_log_level = SDMMC_LOG_NONE; @@ -43,26 +43,30 @@ static void sdmmc_print(sdmmc_t *sdmmc, SdmmcLogLevel log_level, char *fmt, va_l { if (log_level > g_sdmmc_log_level) return; - + + char sdmmc_fmt[] = "%s: "; + ScreenLogLevel screen_log_level = SCREEN_LOG_LEVEL_ERROR; + switch (log_level) { case SDMMC_LOG_ERROR: - printk("%s [ERROR]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_ERROR; break; case SDMMC_LOG_WARN: - printk("%s [WARN]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_WARNING; break; case SDMMC_LOG_INFO: - printk("%s [INFO]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_DEBUG; break; case SDMMC_LOG_DEBUG: - printk("%s [DEBUG]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_DEBUG; break; default: break; } - - vprintk(fmt, list); - printk("\n"); + + print(screen_log_level, sdmmc_fmt, sdmmc->name); + vprint(screen_log_level, fmt, list); + print(screen_log_level | SCREEN_LOG_LEVEL_NO_PREFIX, "\n"); } void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...) diff --git a/fusee/fusee-primary/src/stage2.c b/fusee/fusee-primary/src/stage2.c index c85dab3d9..66b8dcd4b 100644 --- a/fusee/fusee-primary/src/stage2.c +++ b/fusee/fusee-primary/src/stage2.c @@ -21,7 +21,7 @@ #include "fs_utils.h" #include "stage2.h" #include "chainloader.h" -#include "lib/printk.h" +#include "lib/log.h" #include "lib/vsprintf.h" #include "lib/ini.h" #include "lib/fatfs/ff.h" @@ -74,7 +74,7 @@ void load_stage2(const char *bct0) { } if (strlen(config.path) + 1 + sizeof(stage2_args_t) > CHAINLOADER_ARG_DATA_MAX_SIZE) { - printk("Error: Stage2's path name is too big!\n"); + print(SCREEN_LOG_LEVEL_ERROR, "Stage2's path name is too big!\n"); } if (!check_32bit_address_loadable(config.entrypoint)) { @@ -85,10 +85,10 @@ void load_stage2(const char *bct0) { fatal_error("Stage2's load address is invalid!\n"); } - printk("[DEBUG] Stage 2 Config:\n"); - printk(" File Path: %s\n", config.path); - printk(" Load Address: 0x%08x\n", config.load_address); - printk(" Entrypoint: 0x%p\n", config.entrypoint); + print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 Config:\n"); + print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " File Path: %s\n", config.path); + print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Load Address: 0x%08x\n", config.load_address); + print(SCREEN_LOG_LEVEL_DEBUG | SCREEN_LOG_LEVEL_NO_PREFIX, " Entrypoint: 0x%p\n", config.entrypoint); if (f_stat(config.path, &info) != FR_OK) { fatal_error("Failed to stat stage2 (%s)!\n", config.path); diff --git a/fusee/fusee-primary/src/utils.c b/fusee/fusee-primary/src/utils.c index 4a2ec329d..87e84e793 100644 --- a/fusee/fusee-primary/src/utils.c +++ b/fusee/fusee-primary/src/utils.c @@ -25,7 +25,7 @@ #include "car.h" #include "btn.h" -#include "lib/printk.h" +#include "lib/log.h" #include @@ -84,11 +84,11 @@ __attribute__ ((noreturn)) void generic_panic(void) { __attribute__((noreturn)) void fatal_error(const char *fmt, ...) { va_list args; - printk("Fatal error: "); + print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: "); va_start(args, fmt); - vprintk(fmt, args); + vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args); va_end(args); - printk("\nPress POWER to reboot\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX,"\nPress POWER to reboot\n"); wait_for_button_and_reboot(); } @@ -109,27 +109,27 @@ void hexdump(const void* data, size_t size, uintptr_t addrbase) { for (size_t i = 0; i < size; i++) { if (i % 16 == 0) { - printk("%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%0*" PRIXPTR ": | ", 2 * sizeof(addrbase), addrbase + i); } - printk("%02X ", d[i]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%02X ", d[i]); if (d[i] >= ' ' && d[i] <= '~') { ascii[i % 16] = d[i]; } else { ascii[i % 16] = '.'; } if ((i+1) % 8 == 0 || i+1 == size) { - printk(" "); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " "); if ((i+1) % 16 == 0) { - printk("| %s \n", ascii); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "| %s \n", ascii); } else if (i+1 == size) { ascii[(i+1) % 16] = '\0'; if ((i+1) % 16 <= 8) { - printk(" "); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " "); } for (size_t j = (i+1) % 16; j < 16; j++) { - printk(" "); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, " "); } - printk("| %s \n", ascii); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "| %s \n", ascii); } } } diff --git a/fusee/fusee-secondary/src/exception_handlers.c b/fusee/fusee-secondary/src/exception_handlers.c index e8d34f702..42a46516c 100644 --- a/fusee/fusee-secondary/src/exception_handlers.c +++ b/fusee/fusee-secondary/src/exception_handlers.c @@ -17,9 +17,9 @@ #include #include "exception_handlers.h" -#include "lib/driver_utils.h" #include "utils.h" #include "display/video_fb.h" +#include "lib/log.h" #define CODE_DUMP_SIZE 0x30 #define STACK_DUMP_SIZE 0x60 @@ -55,26 +55,28 @@ void exception_handler_main(uint32_t *registers, unsigned int exception_type) { uint32_t instr_addr = pc + ((cpsr & 0x20) ? 2 : 4) - CODE_DUMP_SIZE; - printk("\nSomething went wrong...\n"); + print(SCREEN_LOG_LEVEL_ERROR, "\nSomething went wrong...\n"); code_dump_size = safecpy(code_dump, (const void *)instr_addr, CODE_DUMP_SIZE); stack_dump_size = safecpy(stack_dump, (const void *)registers[13], STACK_DUMP_SIZE); - printk("\nException type: %s\n", exception_names[exception_type]); - printk("\nRegisters:\n\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nException type: %s\n", + exception_names[exception_type]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nRegisters:\n\n"); /* Print r0 to pc. */ for (int i = 0; i < 16; i += 2) { - printk("%-7s%08"PRIX32" %-7s%08"PRIX32"\n", register_names[i], registers[i], register_names[i+1], registers[i+1]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32" %-7s%08"PRIX32"\n", + register_names[i], registers[i], register_names[i+1], registers[i+1]); } /* Print cpsr. */ - printk("%-7s%08"PRIX32"\n", register_names[16], registers[16]); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "%-7s%08"PRIX32"\n", register_names[16], registers[16]); - printk("\nCode dump:\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nCode dump:\n"); hexdump(code_dump, code_dump_size, instr_addr); - printk("\nStack dump:\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\nStack dump:\n"); hexdump(stack_dump, stack_dump_size, registers[13]); - printk("\n"); - fatal_error("An exception occured!\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n"); + fatal_error("An exception occurred!\n"); } diff --git a/fusee/fusee-secondary/src/lib/driver_utils.h b/fusee/fusee-secondary/src/lib/driver_utils.h deleted file mode 100644 index 24cde1ed7..000000000 --- a/fusee/fusee-secondary/src/lib/driver_utils.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2018 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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, see . - */ - -#ifndef FUSEE_DRIVER_UTILS_H -#define FUSEE_DRIVER_UTILS_H - -#include -#include - -#define vprintk vprintf -#define printk printf - -#endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/lib/log.c b/fusee/fusee-secondary/src/lib/log.c new file mode 100644 index 000000000..d4cae38b3 --- /dev/null +++ b/fusee/fusee-secondary/src/lib/log.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#include "log.h" + +#include + +/* default log level for screen output */ +ScreenLogLevel g_screen_log_level = SCREEN_LOG_LEVEL_MANDATORY; + +void log_set_log_level(ScreenLogLevel log_level) { + g_screen_log_level = log_level; +} + +void log_to_uart(const char *message) { + /* TODO: add UART logging */ +} + +void print_to_screen(ScreenLogLevel screen_log_level, char *message) { + /* don't print to screen if below log level */ + if(screen_log_level > g_screen_log_level) return; + + printf(message); +} + +/** + * vprintk - logs a message and prints it to screen based on its screen_log_level + * + * If the level is below g_screen_log_level it will not be shown but logged to UART + * This text will not be colored or prefixed + * UART is TODO + */ +void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args) +{ + char buf[PRINT_MESSAGE_MAX_LENGTH]; + vsnprintf(buf, PRINT_MESSAGE_MAX_LENGTH, fmt, args); + + /* we don't need that flag here, but if it gets used, strip it so we print correctly */ + screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX; + + /* log to UART */ + log_to_uart(buf); + + print_to_screen(screen_log_level, buf); +} + +void add_prefix(ScreenLogLevel screen_log_level, const char *fmt, char *buf) { + char typebuf[] = "[%s] %s"; + + /* apply prefix and append message format */ + /* TODO: add coloring to the output */ + switch(screen_log_level) + { + case SCREEN_LOG_LEVEL_ERROR: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "ERROR", fmt); + break; + case SCREEN_LOG_LEVEL_WARNING: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "WARNING", fmt); + break; + case SCREEN_LOG_LEVEL_MANDATORY: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt); + break; + case SCREEN_LOG_LEVEL_INFO: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "INFO", fmt); + break; + case SCREEN_LOG_LEVEL_DEBUG: + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, typebuf, "DEBUG", fmt); + break; + default: + break; + } +} + +/** + * print - logs a message and prints it to screen based on its screen_log_level + * + * If the level is below g_screen_log_level it will not be shown but logged to UART + * Use SCREEN_LOG_LEVEL_NO_PREFIX if you don't want a prefix to be added + * UART is TODO + */ +void print(ScreenLogLevel screen_log_level, const char * fmt, ...) +{ + char buf[PRINT_MESSAGE_MAX_LENGTH] = {}; + char message[PRINT_MESSAGE_MAX_LENGTH] = {}; + + /* TODO: make splash disappear if level > MANDATORY */ + + /* make prefix free messages with log_level possible */ + if(screen_log_level & SCREEN_LOG_LEVEL_NO_PREFIX) { + /* remove the NO_PREFIX flag so the enum can be recognized later on */ + screen_log_level &= ~SCREEN_LOG_LEVEL_NO_PREFIX; + + snprintf(buf, PRINT_MESSAGE_MAX_LENGTH, "%s", fmt); + } + else { + add_prefix(screen_log_level, fmt, buf); + } + + /* input arguments */ + va_list args; + va_start(args, fmt); + vsnprintf(message, PRINT_MESSAGE_MAX_LENGTH, buf, args); + va_end(args); + + /* log to UART */ + log_to_uart(message); + + print_to_screen(screen_log_level, message); +} \ No newline at end of file diff --git a/fusee/fusee-secondary/src/lib/log.h b/fusee/fusee-secondary/src/lib/log.h new file mode 100644 index 000000000..080f34bef --- /dev/null +++ b/fusee/fusee-secondary/src/lib/log.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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, see . + */ + +#ifndef FUSEE_SECONDARY_PRINT_H +#define FUSEE_SECONDARY_PRINT_H + +#define PRINT_MESSAGE_MAX_LENGTH 512 + +#include + +typedef enum { + SCREEN_LOG_LEVEL_NONE = 0, + SCREEN_LOG_LEVEL_ERROR = 1, + SCREEN_LOG_LEVEL_WARNING = 2, + SCREEN_LOG_LEVEL_MANDATORY = 3, /* no log prefix */ + SCREEN_LOG_LEVEL_INFO = 4, + SCREEN_LOG_LEVEL_DEBUG = 5, + + SCREEN_LOG_LEVEL_NO_PREFIX = 0x100 /* OR this to your LOG_LEVEL to prevent prefix creation */ +} ScreenLogLevel; + +/* TODO: make this configurable by BCT.ini */ +extern ScreenLogLevel g_screen_log_level; + +void log_set_log_level(ScreenLogLevel screen_log_level); +void log_to_uart(const char *message); +void vprint(ScreenLogLevel screen_log_level, const char *fmt, va_list args); +void print(ScreenLogLevel screen_log_level, const char* fmt, ...); + +#endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/loader.c b/fusee/fusee-secondary/src/loader.c index b69695532..f9a2a7a30 100644 --- a/fusee/fusee-secondary/src/loader.c +++ b/fusee/fusee-secondary/src/loader.c @@ -24,6 +24,7 @@ #include "fs_utils.h" #include "stage2.h" #include "lib/ini.h" +#include "lib/log.h" static loader_ctx_t g_loader_ctx = {0}; @@ -103,7 +104,7 @@ static void load_list_entry(const char *key) { } static void parse_loadlist(const char *ll) { - printf("Parsing load list: %s\n", ll); + print(SCREEN_LOG_LEVEL_DEBUG, "Parsing load list: %s\n", ll); char load_list[0x200] = {0}; strncpy(load_list, ll, 0x200 - 1); diff --git a/fusee/fusee-secondary/src/main.c b/fusee/fusee-secondary/src/main.c index 5048bd642..ec2ea8bc4 100644 --- a/fusee/fusee-secondary/src/main.c +++ b/fusee/fusee-secondary/src/main.c @@ -19,6 +19,7 @@ #include #include #include + #include "utils.h" #include "panic.h" #include "exception_handlers.h" @@ -32,6 +33,7 @@ #include "gpt.h" #include "display/video_fb.h" #include "sdmmc/sdmmc.h" +#include "lib/log.h" extern void (*__program_exit_callback)(int rc); @@ -91,23 +93,23 @@ int main(int argc, void **argv) { /* Initialize the display, console, FS, etc. */ setup_env(); - printf(u8"Welcome to Atmosphère Fusée Stage 2!\n"); - printf("Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]); + print(SCREEN_LOG_LEVEL_MANDATORY, u8"Welcome to Atmosphère Fusée Stage 2!\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Stage 2 executing from: %s\n", (const char *)argv[STAGE2_ARGV_PROGRAM_PATH]); /* This will load all remaining binaries off of the SD. */ load_payload(g_stage2_args->bct0); - printf("Loaded payloads!\n"); + print(SCREEN_LOG_LEVEL_INFO, "Loaded payloads!\n"); g_do_nxboot = loader_ctx->chainload_entrypoint == 0; if (g_do_nxboot) { - printf("Now performing nxboot.\n"); + print(SCREEN_LOG_LEVEL_INFO, "Now performing nxboot.\n"); uint32_t boot_memaddr = nxboot_main(); nxboot_finish(boot_memaddr); } else { /* TODO: What else do we want to do in terms of argc/argv? */ const char *path = get_loader_ctx()->file_paths_to_load[get_loader_ctx()->file_id_of_entrypoint]; - printf("Now chainloading.\n"); + print(SCREEN_LOG_LEVEL_INFO, "Now chainloading.\n"); g_chainloader_argc = 1; strcpy(g_chainloader_arg_data, path); } diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 68396210b..83fb6ca3a 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -45,6 +45,7 @@ #define u8 uint8_t #define u32 uint32_t #include "exosphere_bin.h" +#include "lib/log.h" #undef u8 #undef u32 @@ -175,6 +176,7 @@ static void nxboot_move_bootconfig() { fatal_error("[NXBOOT]: Failed to open BootConfig from eMMC!\n"); } if (fread(bootconfig, 0x4000, 1, bcfile) < 1) { + fclose(bcfile); fatal_error("[NXBOOT]: Failed to read BootConfig!\n"); } fclose(bcfile); @@ -218,7 +220,7 @@ uint32_t nxboot_main(void) { } /* Read Package2 from a file, otherwise from its partition(s). */ - printf("[NXBOOT]: Reading package2...\n"); + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Reading package2...\n"); if (loader_ctx->package2_path[0] != '\0') { pk2file = fopen(loader_ctx->package2_path, "rb"); if (pk2file == NULL) { @@ -230,26 +232,29 @@ uint32_t nxboot_main(void) { fatal_error("[NXBOOT]: Failed to open Package2 from eMMC: %s!\n", strerror(errno)); } if (fseek(pk2file, 0x4000, SEEK_SET) != 0) { - fatal_error("[NXBOOT]: Failed to seek Package2 in eMMC: %s!\n", strerror(errno)); fclose(pk2file); + fatal_error("[NXBOOT]: Failed to seek Package2 in eMMC: %s!\n", strerror(errno)); } } setvbuf(pk2file, NULL, _IONBF, 0); /* Workaround. */ if (fread(package2, sizeof(package2_header_t), 1, pk2file) < 1) { + fclose(pk2file); fatal_error("[NXBOOT]: Failed to read Package2!\n"); } package2_size = package2_meta_get_size(&package2->metadata); if ((package2_size > PACKAGE2_SIZE_MAX) || (package2_size <= sizeof(package2_header_t))) { + fclose(pk2file); fatal_error("[NXBOOT]: Package2 is too big or too small!\n"); } if (fread(package2->data, package2_size - sizeof(package2_header_t), 1, pk2file) < 1) { + fclose(pk2file); fatal_error("[NXBOOT]: Failed to read Package2!\n"); } fclose(pk2file); /* Read and parse boot0. */ - printf("[NXBOOT]: Reading boot0...\n"); + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Reading boot0...\n"); boot0 = fopen("boot0:/", "rb"); if ((boot0 == NULL) || (package1_read_and_parse_boot0(&package1loader, &package1loader_size, g_keyblobs, &available_revision, boot0) == -1)) { fatal_error("[NXBOOT]: Couldn't parse boot0: %s!\n", strerror(errno)); @@ -286,17 +291,17 @@ uint32_t nxboot_main(void) { if (!target_firmware) fatal_error("[NXBOOT]: Failed to detect target firmware!\n"); else - printf("[NXBOOT]: Detected target firmware %ld!\n", target_firmware); + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Detected target firmware %ld!\n", target_firmware); /* Setup boot configuration for Exosphère. */ nxboot_configure_exosphere(target_firmware); - + /* Initialize Boot Reason on older firmware versions. */ if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) { - printf("[NXBOOT]: Initializing Boot Reason...\n"); + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Initializing Boot Reason...\n"); nxboot_set_bootreason(); } - + /* Derive keydata. */ if (derive_nx_keydata(MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware, g_keyblobs, available_revision, tsec_fw, tsec_fw_size) != 0) { fatal_error("[NXBOOT]: Key derivation failed!\n"); @@ -311,7 +316,7 @@ uint32_t nxboot_main(void) { /* Allocate memory for the warmboot firmware. */ warmboot_fw = malloc(warmboot_fw_size); - + if (warmboot_fw == NULL) { fatal_error("[NXBOOT]: Out of memory!\n"); } @@ -333,7 +338,7 @@ uint32_t nxboot_main(void) { fatal_error("[NXBOOT]: Could not read the warmboot firmware from Package1!\n"); } } - + /* Select the right address for the warmboot firmware. */ if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) { warmboot_memaddr = (void *)0x8000D000; @@ -342,23 +347,23 @@ uint32_t nxboot_main(void) { } else { warmboot_memaddr = (void *)0x4003D800; } - - printf("[NXBOOT]: Copying warmboot firmware...\n"); - + + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Copying warmboot firmware...\n"); + /* Copy the warmboot firmware and set the address in PMC if necessary. */ if (warmboot_fw && (warmboot_fw_size > 0)) { memcpy(warmboot_memaddr, warmboot_fw, warmboot_fw_size); if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) pmc->scratch1 = (uint32_t)warmboot_memaddr; } - - printf("[NXBOOT]: Rebuilding package2...\n"); - + + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Rebuilding package2...\n"); + /* Patch package2, adding Thermosphère + custom KIPs. */ package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware); - printf(u8"[NXBOOT]: Reading Exosphère...\n"); - + print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Reading Exosphère...\n"); + /* Select the right address for Exosphère. */ if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) { exosphere_memaddr = (void *)0x4002D000; @@ -382,11 +387,11 @@ uint32_t nxboot_main(void) { } else { memcpy(exosphere_memaddr, exosphere_bin, exosphere_bin_size); } - + /* Move BootConfig. */ - printf("[NXBOOT]: Moving BootConfig...\n"); + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Moving BootConfig...\n"); nxboot_move_bootconfig(); - + /* Set 3.0.0/3.0.1/3.0.2 warmboot security check. */ if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware == EXOSPHERE_TARGET_FIRMWARE_300) { const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader; @@ -395,7 +400,7 @@ uint32_t nxboot_main(void) { else if (!strcmp(package1loader_header->build_timestamp, "20170710161758")) pmc->secure_scratch32 = 0x104; /* Warmboot 3.0.1/3.0.2 security check. */ } - + /* Clean up. */ free(package1loader); if (loader_ctx->tsecfw_path[0] != '\0') { @@ -405,8 +410,8 @@ uint32_t nxboot_main(void) { free(warmboot_fw); } free(package2); - - printf("[NXBOOT]: Powering on the CCPLEX...\n"); + + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT]: Powering on the CCPLEX...\n"); /* Display splash screen. */ display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000); diff --git a/fusee/fusee-secondary/src/package2.c b/fusee/fusee-secondary/src/package2.c index 76f5f5704..50eada5f8 100644 --- a/fusee/fusee-secondary/src/package2.c +++ b/fusee/fusee-secondary/src/package2.c @@ -27,6 +27,7 @@ #define u8 uint8_t #define u32 uint32_t #include "thermosphere_bin.h" +#include "lib/log.h" #undef u8 #undef u32 @@ -52,7 +53,7 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm /* First things first: Decrypt Package2 in place. */ package2_decrypt(package2); - printf("Decrypted package2!\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Decrypted package2!\n"); kernel_size = package2_get_src_section(&kernel, package2, PACKAGE2_SECTION_KERNEL); @@ -66,11 +67,11 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm /* Perform any patches we want to the NX kernel. */ package2_patch_kernel(kernel, kernel_size); - printf("Rebuilding the INI1 section...\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Rebuilding the INI1 section...\n"); package2_get_src_section((void *)&orig_ini1, package2, PACKAGE2_SECTION_INI1); /* Perform any patches to the INI1, rebuilding it (This is where our built-in sysmodules will be added.) */ rebuilt_ini1 = package2_rebuild_ini1(orig_ini1, target_firmware); - printf("Rebuilt INI1...\n"); + print(SCREEN_LOG_LEVEL_DEBUG, "Rebuilt INI1...\n"); /* Allocate the rebuilt package2. */ rebuilt_package2_size = sizeof(package2_header_t) + kernel_size + align_to_4(thermosphere_size) + align_to_4(rebuilt_ini1->size); diff --git a/fusee/fusee-secondary/src/sdmmc/sdmmc.c b/fusee/fusee-secondary/src/sdmmc/sdmmc.c index e4a59c046..3aeb59f90 100644 --- a/fusee/fusee-secondary/src/sdmmc/sdmmc.c +++ b/fusee/fusee-secondary/src/sdmmc/sdmmc.c @@ -26,7 +26,6 @@ #include "mmc.h" #include "sd.h" #include "../timers.h" -#include "../lib/driver_utils.h" #define UNSTUFF_BITS(resp,start,size) \ ({ \ diff --git a/fusee/fusee-secondary/src/sdmmc/sdmmc_core.c b/fusee/fusee-secondary/src/sdmmc/sdmmc_core.c index c831493f5..56602bc49 100644 --- a/fusee/fusee-secondary/src/sdmmc/sdmmc_core.c +++ b/fusee/fusee-secondary/src/sdmmc/sdmmc_core.c @@ -30,7 +30,7 @@ #include "../gpio.h" #include "../pmc.h" #include "../max7762x.h" -#include "../lib/driver_utils.h" +#include "../lib/log.h" static SdmmcLogLevel g_sdmmc_log_level = SDMMC_LOG_NONE; @@ -43,26 +43,30 @@ static void sdmmc_print(sdmmc_t *sdmmc, SdmmcLogLevel log_level, char *fmt, va_l { if (log_level > g_sdmmc_log_level) return; + + char sdmmc_fmt[] = "%s: "; + ScreenLogLevel screen_log_level = SCREEN_LOG_LEVEL_ERROR; switch (log_level) { case SDMMC_LOG_ERROR: - printk("%s [ERROR]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_ERROR; break; case SDMMC_LOG_WARN: - printk("%s [WARN]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_WARNING; break; case SDMMC_LOG_INFO: - printk("%s [INFO]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_DEBUG; break; case SDMMC_LOG_DEBUG: - printk("%s [DEBUG]: ", sdmmc->name); + screen_log_level = SCREEN_LOG_LEVEL_DEBUG; break; default: break; } - - vprintk(fmt, list); - printk("\n"); + + print(screen_log_level, sdmmc_fmt, sdmmc->name); + vprint(screen_log_level, fmt, list); + print(screen_log_level | SCREEN_LOG_LEVEL_NO_PREFIX, "\n"); } void sdmmc_error(sdmmc_t *sdmmc, char *fmt, ...) diff --git a/fusee/fusee-secondary/src/utils.c b/fusee/fusee-secondary/src/utils.c index 7f2de0da9..b74e0163d 100644 --- a/fusee/fusee-secondary/src/utils.c +++ b/fusee/fusee-secondary/src/utils.c @@ -24,6 +24,7 @@ #include "timers.h" #include "btn.h" #include "panic.h" +#include "lib/log.h" #include #include @@ -76,17 +77,27 @@ __attribute__((noreturn)) void wait_for_button_and_reboot(void) { } } +void wait_for_button(void) { + uint32_t button; + while (true) { + button = btn_read(); + if (button) { + return; + } + } +} + __attribute__ ((noreturn)) void generic_panic(void) { panic(0xFF000006); } __attribute__((noreturn)) void fatal_error(const char *fmt, ...) { va_list args; - printf("Fatal error: "); + print(SCREEN_LOG_LEVEL_ERROR, "Fatal error: "); va_start(args, fmt); - vprintf(fmt, args); + vprint(SCREEN_LOG_LEVEL_ERROR, fmt, args); va_end(args); - printf("\n Press POWER to reboot.\n"); + print(SCREEN_LOG_LEVEL_ERROR | SCREEN_LOG_LEVEL_NO_PREFIX, "\n Press POWER to reboot.\n"); wait_for_button_and_reboot(); } diff --git a/fusee/fusee-secondary/src/utils.h b/fusee/fusee-secondary/src/utils.h index cfc0cbdf4..3d84a563d 100644 --- a/fusee/fusee-secondary/src/utils.h +++ b/fusee/fusee-secondary/src/utils.h @@ -124,6 +124,7 @@ __attribute__((noreturn)) void watchdog_reboot(void); __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0); __attribute__((noreturn)) void car_reboot(void); __attribute__((noreturn)) void wait_for_button_and_reboot(void); +void wait_for_button(void); __attribute__((noreturn)) void generic_panic(void);