fusee-primary: reboot to self, instead of to RCM

This commit is contained in:
Michael Scire 2019-01-25 23:50:50 -08:00
parent cd8621c632
commit ea02f389ac
5 changed files with 42 additions and 7 deletions

View file

@ -7,6 +7,8 @@ $(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>dev
endif endif
TOPDIR ?= $(CURDIR) TOPDIR ?= $(CURDIR)
AMS := $(TOPDIR)/../../
include $(DEVKITARM)/base_rules include $(DEVKITARM)/base_rules
AMSBRANCH := $(shell git symbolic-ref --short HEAD) AMSBRANCH := $(shell git symbolic-ref --short HEAD)
@ -74,14 +76,15 @@ export OUTPUT := $(CURDIR)/$(TARGET)
export TOPDIR := $(CURDIR) export TOPDIR := $(CURDIR)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(AMS)/exosphere/rebootstub
export DEPSDIR := $(CURDIR)/$(BUILD) export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 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 # 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) 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): $(BUILD):
@[ -d $@ ] || mkdir -p $@ @[ -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 # you need a rule like this for each extension you use as binary data
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%.bin.o : %.bin %.bin.o %_bin.h: %.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@echo $(notdir $<) @echo $(notdir $<)
@$(bin2o) @$(bin2o)

View file

@ -61,6 +61,11 @@
#define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818) #define APBDEV_PMC_SCRATCH190_0 MAKE_PMC_REG(0x818)
#define APBDEV_PMC_SCRATCH200_0 MAKE_PMC_REG(0x840) #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 { typedef struct {
uint32_t cntrl; uint32_t cntrl;
uint32_t sec_disable; uint32_t sec_disable;

View file

@ -29,6 +29,12 @@
#include <inttypes.h> #include <inttypes.h>
#define u8 uint8_t
#define u32 uint32_t
#include "rebootstub_bin.h"
#undef u8
#undef u32
void wait(uint32_t microseconds) { void wait(uint32_t microseconds) {
uint32_t old_time = TIMERUS_CNTR_1US_0; uint32_t old_time = TIMERUS_CNTR_1US_0;
while (TIMERUS_CNTR_1US_0 - old_time <= microseconds) { 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) { __attribute__((noreturn)) void wait_for_button_and_reboot(void) {
uint32_t button; uint32_t button;
while (true) { while (true) {
button = btn_read(); button = btn_read();
if (button & BTN_POWER) { if (button & BTN_POWER) {
pmc_reboot(1 << 1); reboot_to_self();
} }
} }
} }

View file

@ -121,6 +121,7 @@ void hexdump(const void* data, size_t size, uintptr_t addrbase);
__attribute__((noreturn)) void watchdog_reboot(void); __attribute__((noreturn)) void watchdog_reboot(void);
__attribute__((noreturn)) void pmc_reboot(uint32_t scratch0); __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 wait_for_button_and_reboot(void);
__attribute__((noreturn)) void generic_panic(void); __attribute__((noreturn)) void generic_panic(void);