diff options
author | William Wilgus <wilgus.william@gmail.com> | 2024-08-25 11:37:30 -0400 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2024-09-02 13:29:43 -0400 |
commit | a2cc7546d88bf9c4071f0f56f6c43d59654fc212 (patch) | |
tree | ed009cf793dd1b99048a50ebd3e2c55c00ed1d9e | |
parent | c16dbbfd1fb7bf4bc268a4693bbed21497456b30 (diff) | |
download | rockbox-a2cc7546d8.tar.gz rockbox-a2cc7546d8.zip |
Add DeviceData to bootloaders
same vein as bootdata but for devices that need to pass info back to a
running firmware
Change-Id: I0cdcdc0475804dfbbee415ab487104ae8fc8ac69
-rw-r--r-- | apps/debug_menu.c | 36 | ||||
-rw-r--r-- | apps/main.c | 11 | ||||
-rw-r--r-- | firmware/SOURCES | 4 | ||||
-rw-r--r-- | firmware/common/devicedata.c | 88 | ||||
-rw-r--r-- | firmware/common/rb-loader.c | 8 | ||||
-rw-r--r-- | firmware/export/config/erosqnative.h | 3 | ||||
-rw-r--r-- | firmware/export/devicedata.h | 94 | ||||
-rw-r--r-- | firmware/rolo.c | 4 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/crt0.S | 7 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_x1000/system-x1000.c | 14 | ||||
-rw-r--r-- | uisimulator/common/stubs.c | 6 |
11 files changed, 274 insertions, 1 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index a101097004..8e16ff1c21 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -124,6 +124,10 @@ #include "talk.h" +#if defined(HAVE_DEVICEDATA)// && !defined(SIMULATOR) +#include "devicedata.h" +#endif + #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) #include "bootdata.h" #include "multiboot.h" @@ -2625,6 +2629,33 @@ static bool dbg_boot_data(void) } #endif /* defined(HAVE_BOOTDATA) && !defined(SIMULATOR) */ +#if defined(HAVE_DEVICEDATA)// && !defined(SIMULATOR) +static bool dbg_device_data(void) +{ + struct simplelist_info info; + info.scroll_all = true; + simplelist_info_init(&info, "Device data", 1, NULL); + simplelist_set_line_count(0); + + simplelist_addline("Device data"); + +#if defined(EROS_QN) + simplelist_addline("Lcd Version: %d", (int)device_data.lcd_version); +#endif + + simplelist_addline("Device data RAW:"); + for (size_t i = 0; i < device_data.length; i += 4) + { + simplelist_addline("%02x: %02x %02x %02x %02x", i, + device_data.payload[i + 0], device_data.payload[i + 1], + device_data.payload[i + 2], device_data.payload[i + 3]); + } + + return simplelist_show_list(&info); +} +#endif /* defined(HAVE_DEVICEDATA)*/ + + #if defined(IPOD_6G) && !defined(SIMULATOR) #define SYSCFG_MAX_ENTRIES 9 // 9 on iPod Classic/6G @@ -2823,6 +2854,11 @@ static const struct { #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) {"Boot data", dbg_boot_data }, #endif + +#if defined(HAVE_DEVICEDATA)// && !defined(SIMULATOR) + {"Device data", dbg_device_data }, +#endif + #if defined(IPOD_6G) && !defined(SIMULATOR) {"View SysCfg", dbg_syscfg }, #endif diff --git a/apps/main.c b/apps/main.c index 4c7689ce8c..1e8e872296 100644 --- a/apps/main.c +++ b/apps/main.c @@ -78,6 +78,10 @@ #include "bootchart.h" #include "logdiskf.h" #include "bootdata.h" +#if defined(HAVE_DEVICEDATA) +#include "devicedata.h" +#endif + #if (CONFIG_PLATFORM & PLATFORM_ANDROID) #include "notification.h" #endif @@ -176,6 +180,9 @@ int main(void) } list_init(); tree_init(); +#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER) /* SIMULATOR */ + verify_device_data(); +#endif /* Keep the order of this 3 * Must be done before any code uses the multi-screen API */ #ifdef HAVE_USBSTACK @@ -459,6 +466,10 @@ static void init(void) verify_boot_data(); #endif +#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER) + verify_device_data(); +#endif + /* early early early! */ filesystem_init(); diff --git a/firmware/SOURCES b/firmware/SOURCES index 4e6fcbf70c..192cdb711d 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -62,6 +62,10 @@ common/bootdata.c #endif #endif +#if defined(HAVE_DEVICEDATA) +common/devicedata.c +#endif + #ifdef HAVE_SDL target/hosted/sdl/button-sdl.c target/hosted/sdl/kernel-sdl.c diff --git a/firmware/common/devicedata.c b/firmware/common/devicedata.c new file mode 100644 index 0000000000..75fe79d7fa --- /dev/null +++ b/firmware/common/devicedata.c @@ -0,0 +1,88 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2024 by William Wilgus + * + * 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 "devicedata.h" +#include "crc32.h" +#include <stddef.h> +#include <string.h> +#include "debug.h" + +#ifndef BOOTLOADER +void verify_device_data(void) INIT_ATTR; +void verify_device_data(void) +{ + DEBUGF("%s", __func__); + /* verify payload with checksum */ + uint32_t crc = crc_32(device_data.payload, device_data.length, 0xffffffff); + if (crc == device_data.crc) + return; /* return if data is valid */ + + /* Write the default if data is invalid */ + memset(device_data.payload, 0xff, DEVICE_DATA_PAYLOAD_SIZE); /* Invalid data */ + device_data.length = DEVICE_DATA_PAYLOAD_SIZE; + device_data.crc = crc_32(device_data.payload, device_data.length, 0xffffffff); + +} + +/******************************************************************************/ +#endif /* ndef BOOTLOADER ******************************************************/ +/******************************************************************************/ + +#if defined(HAVE_DEVICEDATA) +void __attribute__((weak)) fill_devicedata(struct device_data_t *data) +{ + memset(data->payload, 0xff, data->length); +} +#endif + +/* Write bootdata into location in FIRMWARE marked by magic header + * Assumes buffer is already loaded with the firmware image + * We just need to find the location and write data into the + * payload region along with the crc for later verification and use. + * Returns payload len on success, + * On error returns false + */ +bool write_devicedata(unsigned char* buf, int len) +{ + int search_len = MIN(len, DEVICE_DATA_SEARCH_SIZE) - sizeof(struct device_data_t); + + /* search for decvice data header prior to search_len */ + for(int i = 0; i < search_len; i++) + { + struct device_data_t *data = (struct device_data_t *)&buf[i]; + if (data->magic[0] != DEVICE_DATA_MAGIC0 || + data->magic[1] != DEVICE_DATA_MAGIC1) + continue; + + /* Ignore it if the length extends past the end of the buffer. */ + int data_len = offsetof(struct device_data_t, payload) + data->length; + if (i + data_len > len) + continue; + + fill_devicedata(data); + + /* Calculate payload CRC */ + data->crc = crc_32(data->payload, data->length, 0xffffffff); + return true; + } + + return false; +} + diff --git a/firmware/common/rb-loader.c b/firmware/common/rb-loader.c index 61d8b1ddd2..2f5e06e165 100644 --- a/firmware/common/rb-loader.c +++ b/firmware/common/rb-loader.c @@ -30,6 +30,9 @@ #include "multiboot.h" #endif +#ifdef HAVE_DEVICEDATA +#include "devicedata.h" +#endif /* loads a firmware file from supplied filename * file opened, checks firmware size and checksum * if no error, firmware loaded to supplied buffer @@ -118,7 +121,6 @@ int load_firmware(unsigned char* buf, const char* firmware, int buffer_size) /* if ret is valid breaks from loop to continue loading */ } #endif - if (ret < 0) /* Check default volume, no valid firmware file loaded yet */ { /* First check in BOOTDIR */ @@ -141,5 +143,9 @@ int load_firmware(unsigned char* buf, const char* firmware, int buffer_size) else /* full path passed ROLO etc.*/ ret = load_firmware_filename(buf, firmware, buffer_size); +#ifdef HAVE_DEVICEDATA + write_devicedata(buf, ret); +#endif + return ret; } diff --git a/firmware/export/config/erosqnative.h b/firmware/export/config/erosqnative.h index 26073a5f34..75ead37ba8 100644 --- a/firmware/export/config/erosqnative.h +++ b/firmware/export/config/erosqnative.h @@ -106,6 +106,9 @@ #define HAVE_BOOTDATA #define BOOT_REDIR "rockbox_main.aigo_erosqn" +/* DeviceData */ +#define HAVE_DEVICEDATA + /* USB support */ #ifndef SIMULATOR #define CONFIG_USBOTG USBOTG_DESIGNWARE diff --git a/firmware/export/devicedata.h b/firmware/export/devicedata.h new file mode 100644 index 0000000000..c19b0ca25d --- /dev/null +++ b/firmware/export/devicedata.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2017 by Amaury Pouly + * + * 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. + * + ****************************************************************************/ +#ifndef __RB_DEVICEDATA__ +#define __RB_DEVICEDATA__ + +#ifndef __ASSEMBLER__ +#include <stdint.h> +#include "system.h" +#endif + +/* /!\ This file can be included in assembly files /!\ */ + +/** The device data will be filled by the bootloader with information that might + * be relevant for Rockbox. The bootloader will search for the structure using + * the magic header within the first DEVICE_DATA_SEARCH_SIZE bytes of the binary. + * Typically, this structure should be as close as possible to the entry point */ + +/* Search size for the data structure after entry point */ +#define DEVICE_DATA_SEARCH_SIZE 1024 + +#define DEVICE_DATA_MAGIC0 ('r' | 'b' << 8 | 'd' << 16 | 'e' << 24) +#define DEVICE_DATA_MAGIC1 ('v' | 'i' << 8 | 'c' << 16 | 'e' << 24) + +/* maximum size of payload */ +#define DEVICE_DATA_PAYLOAD_SIZE 4 + +#ifndef __ASSEMBLER__ +/* This is the C structure */ +struct device_data_t +{ + union + { + uint32_t crc; /* crc of payload data (CRC32 with 0xffffffff for initial value) */ + uint32_t magic[2]; /* DEVICE_DATA_MAGIC0/1 */ + }; + + uint32_t length; /* length of the payload */ + + /* add fields here */ + union + { + struct + { +#if defined(EROS_QN) + uint8_t lcd_version; +#endif + }; + uint8_t payload[DEVICE_DATA_PAYLOAD_SIZE]; + }; +} __attribute__((packed)); + + +void fill_devicedata(struct device_data_t *data); +bool write_devicedata(unsigned char* buf, int len); +#ifndef BOOTLOADER +extern struct device_data_t device_data; + +void verify_device_data(void) INIT_ATTR; + +#endif + +#else /* __ASSEMBLER__ */ + +/* This assembler macro implements an empty device data structure with just the magic + * string and payload size */ +.macro put_device_data_here +.global device_data +device_data: + .word DEVICE_DATA_MAGIC0 + .word DEVICE_DATA_MAGIC1 + .word DEVICE_DATA_PAYLOAD_SIZE + .space BOOT_DATA_PAYLOAD_SIZE, 0xff /* payload, initialised with value 0xff */ +.endm + +#endif + +#endif /* __RB_DEVICEDATA__ */ diff --git a/firmware/rolo.c b/firmware/rolo.c index 0990b2732f..7be78f8a49 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c @@ -274,6 +274,10 @@ int rolo_load(const char* filename) } #endif +#if defined(HAVE_DEVICEDATA) + write_devicedata(filebuf, filebuf_size); +#endif + if (err <= 0) { rolo_error(loader_strerror(err)); diff --git a/firmware/target/mips/ingenic_x1000/crt0.S b/firmware/target/mips/ingenic_x1000/crt0.S index 6c0942b0db..23daaefb5e 100644 --- a/firmware/target/mips/ingenic_x1000/crt0.S +++ b/firmware/target/mips/ingenic_x1000/crt0.S @@ -23,6 +23,10 @@ #include "mips.h" #include "bootdata.h" +#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER) +#include "devicedata.h" +#endif + .text .extern main .extern system_early_init @@ -52,6 +56,9 @@ _header: #ifndef BOOTLOADER /* Multiboot support header; this is not part of the above header. */ put_boot_data_here +#ifdef HAVE_DEVICEDATA + put_device_data_here +#endif #endif _realstart: diff --git a/firmware/target/mips/ingenic_x1000/system-x1000.c b/firmware/target/mips/ingenic_x1000/system-x1000.c index 64890a6c3a..32ac66ec92 100644 --- a/firmware/target/mips/ingenic_x1000/system-x1000.c +++ b/firmware/target/mips/ingenic_x1000/system-x1000.c @@ -81,6 +81,20 @@ void system_early_init(void) clk_init(); } +#if defined (HAVE_DEVICEDATA) && defined(EROS_QN) +void fill_devicedata(struct device_data_t *data) +{ +#ifdef BOOTLOADER + memset(data->payload, 0xff, data->length); + data->lcd_version = EROSQN_VER; +#else + uint8_t lcd_version = data->lcd_version; + memset(data->payload, 0xff, data->length); + data->lcd_version = lcd_version; +#endif +} +#endif + /* First thing called from Rockbox main() */ void system_init(void) { diff --git a/uisimulator/common/stubs.c b/uisimulator/common/stubs.c index bce7e07227..ba5e2c9908 100644 --- a/uisimulator/common/stubs.c +++ b/uisimulator/common/stubs.c @@ -35,6 +35,12 @@ static bool storage_spinning = false; +#if defined(HAVE_DEVICEDATA) +#include "devicedata.h" +struct device_data_t device_data = + {.length = DEVICE_DATA_PAYLOAD_SIZE}; +#endif /* def HAVE_DEVICEDATA */ + int fat_startsector(void) { return 63; |