diff --git a/fusee/fusee-secondary/src/console.c b/fusee/fusee-secondary/src/console.c index 0d3c1270e..c69f730a1 100644 --- a/fusee/fusee-secondary/src/console.c +++ b/fusee/fusee-secondary/src/console.c @@ -2,11 +2,17 @@ #include #include #include +#include #include #include "console.h" +#include "hwinit.h" #include "display/video_fb.h" +static void *g_framebuffer = NULL; +static bool g_display_initialized = false; + static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t len); +static void console_init_display(void); static const devoptab_t dotab_stdout = { .name = "con", @@ -14,7 +20,7 @@ static const devoptab_t dotab_stdout = { }; /* https://github.com/switchbrew/libnx/blob/master/nx/source/runtime/util/utf/decode_utf8.c */ -ssize_t decode_utf8(uint32_t *out, const uint8_t *in) { +static ssize_t decode_utf8(uint32_t *out, const uint8_t *in) { uint8_t code1, code2, code3, code4; code1 = *in++; @@ -80,8 +86,25 @@ ssize_t decode_utf8(uint32_t *out, const uint8_t *in) { return -1; } +static void console_init_display(void) { + /* Initialize the display. */ + display_init(); + + /* Set the framebuffer. */ + display_init_framebuffer(g_framebuffer); + + /* Turn on the backlight after initializing the lfb */ + /* to avoid flickering. */ + display_enable_backlight(true); + + g_display_initialized = true; +} + static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t len) { size_t i = 0; + if (!g_display_initialized) { + console_init_display(); + } while (i < len) { uint32_t chr; ssize_t n = decode_utf8(&chr, (uint8_t *)(ptr + i)); @@ -96,13 +119,17 @@ static ssize_t console_write(struct _reent *r, void *fd, const char *ptr, size_t return i; } -static bool g_console_created = false; - static int console_create(void) { - if (g_console_created) { + if (g_framebuffer != NULL) { errno = EEXIST; return -1; } + g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE); + + if (g_framebuffer == NULL) { + errno = ENOMEM; + return -1; + } devoptab_list[STD_OUT] = &dotab_stdout; devoptab_list[STD_ERR] = &dotab_stdout; @@ -110,23 +137,51 @@ static int console_create(void) { setvbuf(stdout, NULL , _IOLBF, 4096); setvbuf(stderr, NULL , _IONBF, 0); - g_console_created = true; return 0; } -int console_init(void *fb) { - if (video_init(fb) == -1) { - errno = EIO; +int console_init(void) { + if (console_create() == -1) { return -1; } - return console_create(); -} - -int console_resume(void *fb, int row, int col) { - video_resume(fb, row, col); if(false){// if (video_resume(fb, row, col) == -1) { + /* Zero-fill the framebuffer, etc. */ + if (video_init(g_framebuffer) == -1) { errno = EIO; + console_end(); return -1; } - return console_create(); + + return 0; +} + +int console_display(const void *framebuffer) { + if (!g_display_initialized) { + console_init_display(); + } + + /* TODO: does this work? */ + display_init_framebuffer((void *)framebuffer); + return 0; +} + +int console_resume(void) { + if (!g_display_initialized) { + console_init_display(); + } else { + /* TODO: does this work? */ + display_init_framebuffer(g_framebuffer); + } + return 0; +} + +int console_end(void) { + /* Deinitialize the framebuffer and display */ + if (g_display_initialized) { + display_enable_backlight(false); + display_end(); + } + free(g_framebuffer); + g_framebuffer = NULL; + return 0; } diff --git a/fusee/fusee-secondary/src/console.h b/fusee/fusee-secondary/src/console.h index f46954427..76d8c37f6 100644 --- a/fusee/fusee-secondary/src/console.h +++ b/fusee/fusee-secondary/src/console.h @@ -1,7 +1,9 @@ #ifndef FUSEE_CONSOLE_H #define FUSEE_CONSOLE_H -int console_init(void *fb); -int console_resume(void *fb, int row, int col); +int console_init(void); +int console_display(const void *framebuffer); /* Must be page-aligned */ +int console_resume(void); +int console_end(void); #endif diff --git a/fusee/fusee-secondary/src/main.c b/fusee/fusee-secondary/src/main.c index 7e791c84e..710ff1cac 100644 --- a/fusee/fusee-secondary/src/main.c +++ b/fusee/fusee-secondary/src/main.c @@ -3,7 +3,6 @@ #include #include #include "utils.h" -#include "hwinit.h" #include "loader.h" #include "chainloader.h" #include "stage2.h" @@ -16,30 +15,14 @@ extern void (*__program_exit_callback)(int rc); static stage2_args_t *g_stage2_args; -static void *g_framebuffer; static bool g_do_nxboot; static void setup_env(void) { - g_framebuffer = memalign(0x1000, CONFIG_VIDEO_VISIBLE_ROWS * CONFIG_VIDEO_COLS * CONFIG_VIDEO_PIXEL_SIZE); - - /* Note: the framebuffer needs to be >= 0xC0000000, this is fine because of where our heap is. */ - if (g_framebuffer == NULL) { + /* Set the console up. */ + if (console_init() == -1) { generic_panic(); } - /* Zero-fill the framebuffer and set the console up. */ - console_init(g_framebuffer); - - /* Initialize the display. */ - display_init(); - - /* Set the framebuffer. */ - display_init_framebuffer(g_framebuffer); - - /* Turn on the backlight after initializing the lfb */ - /* to avoid flickering. */ - display_enable_backlight(true); - initialize_sd(); if(fsdev_mount_all() == -1) { perror("Failed to mount at least one FAT parition"); @@ -53,12 +36,7 @@ static void setup_env(void) { static void cleanup_env(void) { /* Unmount everything (this causes all open files to be flushed and closed) */ fsdev_unmount_all(); - - /* Deinitialize the framebuffer and display */ - /*display_enable_backlight(false); - display_end(); - free(g_framebuffer); - g_framebuffer = NULL;*/ + //console_end(); } static void exit_callback(int rc) {