From dbc1f665f792f429167b3e7df77b557a501b1708 Mon Sep 17 00:00:00 2001
From: Andrew Dennison <andrew@motec.com.au>
Date: Wed, 7 Feb 2024 17:26:23 +1100
Subject: [PATCH 1/3] software/bios/boot: fix warnings

---
 litex/soc/software/bios/boot.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/litex/soc/software/bios/boot.c b/litex/soc/software/bios/boot.c
index 7c62409e42..67abc88c28 100755
--- a/litex/soc/software/bios/boot.c
+++ b/litex/soc/software/bios/boot.c
@@ -7,6 +7,7 @@
 // This file is Copyright (c) 2018 William D. Jones <thor0505@comcast.net>
 // License: BSD
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -589,14 +590,14 @@ static unsigned int check_image_in_flash(unsigned int base_address)
 
 	length = MMPTR(base_address);
 	if((length < 32) || (length > 16*1024*1024)) {
-		printf("Error: Invalid image length 0x%08x\n", length);
+		printf("Error: Invalid image length 0x%" PRIx32 "\n", length);
 		return 0;
 	}
 
 	crc = MMPTR(base_address + 4);
 	got_crc = crc32((unsigned char *)(base_address + 8), length);
 	if(crc != got_crc) {
-		printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc);
+		printf("CRC failed (expected 0x%" PRIx32 ", got 0x%" PRIx32 ")\n", crc, got_crc);
 		return 0;
 	}
 
@@ -611,7 +612,7 @@ static int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned lon
 
 	length = check_image_in_flash(flash_address);
 	if(length > 0) {
-		printf("Copying 0x%08x to 0x%08lx (%d bytes)...\n", flash_address, ram_address, length);
+		printf("Copying 0x%08x to 0x%08lx (%" PRIu32 " bytes)...\n", flash_address, ram_address, length);
 		offset = 0;
 		init_progression_bar(length);
 		while (length > 0) {

From 93a7cc2523f1af8f17aeb0c5872ae8944c38e7eb Mon Sep 17 00:00:00 2001
From: Denis Ryndine <denis.ryndine@motec.com.au>
Date: Tue, 13 Feb 2024 21:56:06 +0000
Subject: [PATCH 2/3] cmd_bios.c: Fix wrong byte size of uptime in
 uptime_handler.

  - It's a 64bit not 32bit unsigned and it caused overflow/negative
    cycles display.
---
 litex/soc/software/bios/cmds/cmd_bios.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/litex/soc/software/bios/cmds/cmd_bios.c b/litex/soc/software/bios/cmds/cmd_bios.c
index 5acf671403..db6d1cbf0b 100644
--- a/litex/soc/software/bios/cmds/cmd_bios.c
+++ b/litex/soc/software/bios/cmds/cmd_bios.c
@@ -73,13 +73,13 @@ define_command(ident, ident_handler, "Identifier of the system", SYSTEM_CMDS);
 #ifdef CSR_TIMER0_UPTIME_CYCLES_ADDR
 static void uptime_handler(int nb_params, char **params)
 {
-	unsigned long uptime;
+	uint64_t uptime;
 
 	timer0_uptime_latch_write(1);
 	uptime = timer0_uptime_cycles_read();
-	printf("Uptime: %ld sys_clk cycles / %ld seconds",
-		uptime,
-		uptime/CONFIG_CLOCK_FREQUENCY
+	printf("Uptime: %" PRIu64 " sys_clk cycles / %" PRIu64 " seconds\n",
+				uptime,
+				uptime / CONFIG_CLOCK_FREQUENCY
 	);
 }
 

From 222848298f55d9f85b2fecaab097ccac8b479034 Mon Sep 17 00:00:00 2001
From: Andrew Dennison <andrew@motec.com.au>
Date: Thu, 29 Feb 2024 12:41:28 +1100
Subject: [PATCH 3/3] software/bios: add target hooks

This allows the target to supply custom target_init() and target_boot()
functions, eg:

    # add custom target specific library to the bios:
    src="libtarget"
    src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), src))
    builder.add_software_package(src, src_dir)
    builder.add_software_library(src)
---
 litex/soc/software/bios/boot.c | 8 +++++---
 litex/soc/software/bios/boot.h | 3 +++
 litex/soc/software/bios/main.c | 6 ++++++
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/litex/soc/software/bios/boot.c b/litex/soc/software/bios/boot.c
index 67abc88c28..bcd72f0ba4 100755
--- a/litex/soc/software/bios/boot.c
+++ b/litex/soc/software/bios/boot.c
@@ -580,7 +580,7 @@ void netboot(int nb_params, char **params)
 /* Flash Boot                                                            */
 /*-----------------------------------------------------------------------*/
 
-#ifdef FLASH_BOOT_ADDRESS
+#if defined(FLASH_BOOT_ADDRESS) || defined(MAIN_RAM_BASE)
 
 static unsigned int check_image_in_flash(unsigned int base_address)
 {
@@ -603,9 +603,10 @@ static unsigned int check_image_in_flash(unsigned int base_address)
 
 	return length;
 }
+#endif
 
-#if defined(MAIN_RAM_BASE) && defined(FLASH_BOOT_ADDRESS)
-static int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned long ram_address)
+#if defined(MAIN_RAM_BASE)
+int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned long ram_address)
 {
 	uint32_t length;
 	uint32_t offset;
@@ -632,6 +633,7 @@ static int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned lon
 }
 #endif
 
+#if defined(FLASH_BOOT_ADDRESS)
 void flashboot(void)
 {
 	uint32_t length;
diff --git a/litex/soc/software/bios/boot.h b/litex/soc/software/bios/boot.h
index 338312d090..9128292b17 100644
--- a/litex/soc/software/bios/boot.h
+++ b/litex/soc/software/bios/boot.h
@@ -12,5 +12,8 @@ void flashboot(void);
 void romboot(void);
 void sdcardboot(void);
 void sataboot(void);
+extern void target_init(void) __attribute__((weak));
+extern void target_boot(void) __attribute__((weak));
+extern int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned long ram_address);
 
 #endif /* __BOOT_H */
diff --git a/litex/soc/software/bios/main.c b/litex/soc/software/bios/main.c
index e576b6878c..5e4d9abfb5 100644
--- a/litex/soc/software/bios/main.c
+++ b/litex/soc/software/bios/main.c
@@ -57,6 +57,8 @@ static void boot_sequence(void)
 	if (serialboot() == 0)
 		return;
 #endif
+	if (target_boot)
+		target_boot();
 #ifdef FLASH_BOOT_ADDRESS
 	flashboot();
 #endif
@@ -297,6 +299,10 @@ __attribute__((__used__)) int main(int i, char **c)
 	/* Execute  initialization functions */
 	init_dispatcher();
 
+	/* Execute any target specific initialisation (if linked) */
+	if (target_init)
+		target_init();
+
 	/* Execute Boot sequence */
 #ifndef CONFIG_BIOS_NO_BOOT
 	if(sdr_ok) {