diff --git a/fusee/fusee-primary/Makefile b/fusee/fusee-primary/Makefile index cf79835f8..724c4083f 100644 --- a/fusee/fusee-primary/Makefile +++ b/fusee/fusee-primary/Makefile @@ -7,6 +7,8 @@ $(error "Please set DEVKITARM in your environment. export DEVKITARM=dev endif TOPDIR ?= $(CURDIR) + +AMS := $(TOPDIR)/../../ include $(DEVKITARM)/base_rules AMSBRANCH := $(shell git symbolic-ref --short HEAD) @@ -74,14 +76,15 @@ export OUTPUT := $(CURDIR)/$(TARGET) export TOPDIR := $(CURDIR) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(AMS)/exosphere/rebootstub export DEPSDIR := $(CURDIR)/$(BUILD) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) rebootstub.bin #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -108,10 +111,13 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) -.PHONY: $(BUILD) clean all +.PHONY: $(BUILD) clean all check_rebootstub #--------------------------------------------------------------------------------- -all: $(BUILD) +all: check_rebootstub $(BUILD) + +check_rebootstub: + @$(MAKE) -C $(AMS)/exosphere/rebootstub all $(BUILD): @[ -d $@ ] || mkdir -p $@ @@ -150,7 +156,7 @@ $(OFILES_SRC) : $(HFILES_BIN) #--------------------------------------------------------------------------------- # you need a rule like this for each extension you use as binary data #--------------------------------------------------------------------------------- -%.bin.o : %.bin +%.bin.o %_bin.h: %.bin #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) diff --git a/fusee/fusee-primary/src/main.c b/fusee/fusee-primary/src/main.c index c54862ba8..718130467 100644 --- a/fusee/fusee-primary/src/main.c +++ b/fusee/fusee-primary/src/main.c @@ -163,7 +163,7 @@ int main(void) { stage2_args->display_initialized = false; strcpy(stage2_args->bct0, bct0); g_chainloader_argc = 2; - + /* Wait a while. */ mdelay(1000); diff --git a/fusee/fusee-primary/src/pmc.h b/fusee/fusee-primary/src/pmc.h index cf20474e7..80c36da7f 100644 --- a/fusee/fusee-primary/src/pmc.h +++ b/fusee/fusee-primary/src/pmc.h @@ -61,6 +61,11 @@ #define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) #define APBDEV_PMC_SCRATCH200_0 MAKE_PMC_REG(0x840) +#define APBDEV_PMC_SCRATCH45_0 MAKE_PMC_REG(0x234) +#define APBDEV_PMC_SCRATCH46_0 MAKE_PMC_REG(0x238) +#define APBDEV_PMC_SCRATCH33_0 MAKE_PMC_REG(0x120) +#define APBDEV_PMC_SCRATCH40_0 MAKE_PMC_REG(0x13C) + typedef struct { uint32_t cntrl; uint32_t sec_disable; diff --git a/fusee/fusee-primary/src/utils.c b/fusee/fusee-primary/src/utils.c index 26e838130..ac3d7b61f 100644 --- a/fusee/fusee-primary/src/utils.c +++ b/fusee/fusee-primary/src/utils.c @@ -29,6 +29,12 @@ #include +#define u8 uint8_t +#define u32 uint32_t +#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) { @@ -59,12 +65,29 @@ __attribute__((noreturn)) void pmc_reboot(uint32_t scratch0) { } } +__attribute__((noreturn)) void reboot_to_self(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 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_self(); } } } diff --git a/fusee/fusee-primary/src/utils.h b/fusee/fusee-primary/src/utils.h index 23893e930..58e53bffe 100644 --- a/fusee/fusee-primary/src/utils.h +++ b/fusee/fusee-primary/src/utils.h @@ -121,6 +121,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_self(void); __attribute__((noreturn)) void wait_for_button_and_reboot(void); __attribute__((noreturn)) void generic_panic(void);