diff --git a/fusee/fusee-primary/Makefile b/fusee/fusee-primary/Makefile index 724c4083f..107b32f55 100644 --- a/fusee/fusee-primary/Makefile +++ b/fusee/fusee-primary/Makefile @@ -126,6 +126,7 @@ $(BUILD): #--------------------------------------------------------------------------------- clean: @echo clean ... + @$(MAKE) -C $(AMS)/exosphere/rebootstub clean @rm -fr $(BUILD) $(TARGET).bin $(TARGET).elf diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile index 90e963b63..8a964e2d3 100644 --- a/fusee/fusee-secondary/Makefile +++ b/fusee/fusee-secondary/Makefile @@ -19,6 +19,13 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null))) AMSREV := $(AMSREV)-dirty endif +define _bin2o + bin2s $< | $(AS) -o $(@) + echo "extern const u8" `(echo $( `(echo $(> `(echo $(> `(echo $( #include +#define u8 uint8_t +#define u32 uint32_t +#include "fusee_primary_bin.h" +#include "rebootstub_bin.h" +#undef u8 +#undef u32 + void wait(uint32_t microseconds) { uint32_t old_time = TIMERUS_CNTR_1US_0; while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) { @@ -58,12 +65,34 @@ __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) { } } +__attribute__((noreturn)) void reboot_to_fusee_primary(void) { + /* Patch SDRAM init to perform an SVC immediately after second write */ + APBDEV_PMC_SCRATCH45_0 = 0x2E38DFFF; + APBDEV_PMC_SCRATCH46_0 = 0x6001DC28; + /* Set SVC handler to jump to reboot stub in IRAM. */ + APBDEV_PMC_SCRATCH33_0 = 0x4003F000; + APBDEV_PMC_SCRATCH40_0 = 0x6000F208; + + /* Copy fusee-primary into IRAM low. */ + for (size_t i = 0; i < fusee_primary_bin_size; i += sizeof(uint32_t)) { + write32le((void *)0x40010000, i, read32le(fusee_primary_bin, i)); + } + + /* Copy reboot stub into IRAM high. */ + for (size_t i = 0; i < rebootstub_bin_size; i += sizeof(uint32_t)) { + write32le((void *)0x4003F000, i, read32le(rebootstub_bin, i)); + } + + /* Trigger warm reboot. */ + pmc_reboot(1 << 0); +} + __attribute__((noreturn)) void wait_for_button_and_reboot(void) { uint32_t button; while (true) { button = btn_read(); if (button & BTN_POWER) { - pmc_reboot(1 << 1); + reboot_to_fusee_primary(); } } } diff --git a/fusee/fusee-secondary/src/utils.h b/fusee/fusee-secondary/src/utils.h index 6b26428ce..8cc3e6814 100644 --- a/fusee/fusee-secondary/src/utils.h +++ b/fusee/fusee-secondary/src/utils.h @@ -122,6 +122,7 @@ void hexdump(const void* data, size_t size, uintptr_t addrbase); __attribute__((noreturn)) void watchdog_reboot(void); __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0); +__attribute__((noreturn)) void reboot_to_fusee_primary(void); __attribute__((noreturn)) void wait_for_button_and_reboot(void); void wait_for_button(void);