fusee: Add support for firmware version 6.0.0.

fusee: Implement splash screen rendering.
fusee: Add minor notes and update lz library.
This commit is contained in:
hexkyz
2018-09-17 21:03:03 +01:00
parent 39d812f434
commit f864b0835d
10 changed files with 337 additions and 44 deletions

View File

@@ -27,9 +27,10 @@
#define EXOSPHERE_TARGET_FIRMWARE_300 3
#define EXOSPHERE_TARGET_FIRMWARE_400 4
#define EXOSPHERE_TARGET_FIRMWARE_500 5
#define EXOSPHERE_TARGET_FIRMWARE_600 6
#define EXOSPHERE_TARGET_FIRMWARE_MIN EXOSPHERE_TARGET_FIRMWARE_100
#define EXOSPHERE_TARGET_FIRMWARE_MAX EXOSPHERE_TARGET_FIRMWARE_500
#define EXOSPHERE_TARGET_FIRMWARE_MAX EXOSPHERE_TARGET_FIRMWARE_600
typedef struct {
unsigned int magic;

View File

@@ -75,6 +75,8 @@ static uint32_t nxboot_get_target_firmware(const void *package1loader) {
return EXOSPHERE_TARGET_FIRMWARE_400;
case 0x0B: /* 5.0.0 - 5.1.0 */
return EXOSPHERE_TARGET_FIRMWARE_500;
case 0x0E: /* 6.0.0 */
return EXOSPHERE_TARGET_FIRMWARE_600;
default:
return 0;
}
@@ -158,6 +160,8 @@ static void nxboot_set_bootreason() {
static void nxboot_move_bootconfig() {
FILE *bcfile;
void *bootconfig;
uint32_t bootconfig_addr;
uint32_t bootconfig_size;
/* Allocate memory for reading BootConfig. */
bootconfig = memalign(0x1000, 0x4000);
@@ -175,9 +179,13 @@ static void nxboot_move_bootconfig() {
}
fclose(bcfile);
/* Copy the first 0x3000 bytes into IRAM. */
memset((void *)0x4003D000, 0, 0x3000);
memcpy((void *)0x4003D000, bootconfig, 0x3000);
/* Select the actual BootConfig size and destination address. */
bootconfig_addr = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_600) ? 0x4003D000 : 0x4003F800;
bootconfig_size = (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) ? 0x3000 : 0x1000;
/* Copy the BootConfig into IRAM. */
memset((void *)bootconfig_addr, 0, bootconfig_size);
memcpy((void *)bootconfig_addr, bootconfig, bootconfig_size);
/* Clean up. */
free(bootconfig);
@@ -329,8 +337,10 @@ uint32_t nxboot_main(void) {
/* Select the right address for the warmboot firmware. */
if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_400) {
warmboot_memaddr = (void *)0x8000D000;
} else {
} else if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < EXOSPHERE_TARGET_FIRMWARE_600) {
warmboot_memaddr = (void *)0x4003B000;
} else {
warmboot_memaddr = (void *)0x4003D800;
}
printf("[NXBOOT]: Copying warmboot firmware...\n");
@@ -399,7 +409,7 @@ uint32_t nxboot_main(void) {
printf("[NXBOOT]: Powering on the CCPLEX...\n");
/* Display splash screen. */
display_splash_screen_bmp(loader_ctx->custom_splash_path);
display_splash_screen_bmp(loader_ctx->custom_splash_path, (void *)0xC0000000);
/* Unmount everything. */
nxfs_unmount_all();

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

View File

@@ -15,20 +15,75 @@
*/
#include <stdio.h>
#include "di.h"
#include "timers.h"
#include "splash_screen.h"
#include "fs_utils.h"
#include "display/video_fb.h"
void display_splash_screen_bmp(const char *custom_splash_path) {
uint8_t *splash_screen = g_default_splash_screen;
#define u8 uint8_t
#define u32 uint32_t
#include "splash_screen_bmp.h"
#undef u8
#undef u32
static void render_bmp(const uint32_t *bmp_data, uint32_t *framebuffer, uint32_t bmp_width, uint32_t bmp_height, uint32_t bmp_pos_x, uint32_t bmp_pos_y) {
/* Render the BMP. */
for (uint32_t y = bmp_pos_y; y < (bmp_pos_y + bmp_height); y++) {
for (uint32_t x = bmp_pos_x; x < (bmp_pos_x + bmp_width); x++) {
framebuffer[x + (y * SPLASH_SCREEN_STRIDE)] = bmp_data[(bmp_height + bmp_pos_y - 1 - y) * bmp_width + x - bmp_pos_x];
}
}
/* Re-initialize the frame buffer. */
display_init_framebuffer(framebuffer);
}
void display_splash_screen_bmp(const char *custom_splash_path, void *fb_address) {
uint8_t *splash_screen = (uint8_t *)splash_screen_bmp;
/* Try to load an external custom splash screen. */
if ((custom_splash_path != NULL) && (custom_splash_path[0] != '\x00')) {
if (!read_from_file(splash_screen, sizeof(g_default_splash_screen), custom_splash_path)) {
if (!read_from_file(splash_screen, sizeof(&splash_screen_bmp), custom_splash_path)) {
fatal_error("Failed to read custom splash screen from %s!\n", custom_splash_path);
}
}
/* TODO: Display the splash screen. It should be a pointer to a BMP, at this point. */
/* Check for 'BM' magic. */
if ((splash_screen[0] == 'B') && (splash_screen[1] == 'M')) {
/* Extract BMP parameters. */
uint32_t bmp_size = (splash_screen[0x02] | (splash_screen[0x03] << 8) | (splash_screen[0x04] << 16) | (splash_screen[0x05] << 24));
uint32_t bmp_offset = (splash_screen[0x0A] | (splash_screen[0x0B] << 8) | (splash_screen[0x0C] << 16) | (splash_screen[0x0D] << 24));
uint32_t bmp_width = (splash_screen[0x12] | (splash_screen[0x13] << 8) | (splash_screen[0x14] << 16) | (splash_screen[0x15] << 24));
uint32_t bmp_height = (splash_screen[0x16] | (splash_screen[0x17] << 8) | (splash_screen[0x18] << 16) | (splash_screen[0x19] << 24));
uint16_t bmp_bpp = (splash_screen[0x1C] | (splash_screen[0x1D] << 8));
uint32_t bmp_data_size = (splash_screen[0x22] | (splash_screen[0x23] << 8) | (splash_screen[0x24] << 16) | (splash_screen[0x25] << 24));
/* Data size can be wrong or set to 0. In that case, we calculate it instead. */
if (!bmp_data_size || (bmp_data_size >= bmp_size))
bmp_data_size = (bmp_size - bmp_offset);
/* Only accept images up to 720x1280 resolution and with 32 BPP. */
if ((bmp_width > SPLASH_SCREEN_WIDTH_MAX) || (bmp_height > SPLASH_SCREEN_HEIGHT_MAX)) {
fatal_error("Invalid splash screen dimensions!\n");
} else if (bmp_bpp != SPLASH_SCREEN_BPP) {
fatal_error("Invalid splash screen color depth!\n");
} else if (bmp_data_size > SPLASH_SCREEN_SIZE_MAX) {
fatal_error("Splash screen data size is too big!\n");
}
/* Calculate screen positions. */
uint32_t bmp_pos_x = ((SPLASH_SCREEN_WIDTH_MAX - bmp_width) / 2);
uint32_t bmp_pos_y = ((SPLASH_SCREEN_HEIGHT_MAX - bmp_height) / 2);
/* Advance to data. */
splash_screen += bmp_offset;
/* Render the BMP. */
render_bmp((uint32_t *)splash_screen, (uint32_t *)fb_address, bmp_width, bmp_height, bmp_pos_x, bmp_pos_y);
} else {
fatal_error("Invalid splash screen format!\n");
}
/* Display the splash screen for three seconds. */
udelay(3000000);

View File

@@ -19,9 +19,12 @@
#include <stdint.h>
/* TODO: Actually make this a real thing. */
extern unsigned char g_default_splash_screen[1];
#define SPLASH_SCREEN_WIDTH_MAX 720
#define SPLASH_SCREEN_HEIGHT_MAX 1280
#define SPLASH_SCREEN_BPP 32
#define SPLASH_SCREEN_STRIDE 768
#define SPLASH_SCREEN_SIZE_MAX (SPLASH_SCREEN_HEIGHT_MAX * SPLASH_SCREEN_STRIDE * 4)
void display_splash_screen_bmp(const char *custom_splash_path);
void display_splash_screen_bmp(const char *custom_splash_path, void *fb_address);
#endif

View File

@@ -1,19 +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 <http://www.gnu.org/licenses/>.
*/
#include "splash_screen.h"
uint8_t g_default_splash_screen[1] = {0};