mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[bootloader] Boot other slot if a slot is invalid
This commit is contained in:
@@ -29,18 +29,34 @@ void Boot::setMode(BootMode mode) {
|
||||
Ion::ExamMode::IncrementExamMode(deltaMode);
|
||||
}
|
||||
|
||||
[[ noreturn ]] void Boot::boot() {
|
||||
__attribute__((noreturn)) void Boot::boot() {
|
||||
assert(mode() != BootMode::Unknown);
|
||||
|
||||
if (mode() == BootMode::SlotA)
|
||||
Slot::A().boot();
|
||||
else if (mode() == BootMode::SlotB)
|
||||
if (!Slot::A().kernelHeader()->isValid() && !Slot::B().kernelHeader()->isValid()) {
|
||||
// Bootloader if both invalid
|
||||
bootloader();
|
||||
} else if (!Slot::A().kernelHeader()->isValid()) {
|
||||
// If slot A is invalid and B valid, boot B
|
||||
setMode(BootMode::SlotB);
|
||||
Slot::B().boot();
|
||||
|
||||
for(;;);
|
||||
} else if (!Slot::B().kernelHeader()->isValid()) {
|
||||
// If slot B is invalid and A valid, boot A
|
||||
setMode(BootMode::SlotA);
|
||||
Slot::A().boot();
|
||||
} else {
|
||||
// Both valid, boot the selected one
|
||||
if (mode() == BootMode::SlotA) {
|
||||
Slot::A().boot();
|
||||
} else if (mode() == BootMode::SlotB) {
|
||||
Slot::B().boot();
|
||||
}
|
||||
}
|
||||
|
||||
// Achivement unlocked: How Did We Get Here?
|
||||
bootloader();
|
||||
}
|
||||
|
||||
[[ noreturn ]] void Boot::bootloader() {
|
||||
__attribute__ ((noreturn)) void Boot::bootloader() {
|
||||
Bootloader::Interface::draw();
|
||||
for(;;) {
|
||||
Ion::USB::enable();
|
||||
|
||||
@@ -19,8 +19,8 @@ class Boot {
|
||||
public:
|
||||
static BootMode mode();
|
||||
static void setMode(BootMode mode);
|
||||
[[ noreturn ]] static void boot();
|
||||
[[ norteurn ]] static void bootloader();
|
||||
__attribute__ ((noreturn)) static void boot();
|
||||
__attribute__ ((noreturn)) static void bootloader();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
|
||||
#include <ion.h>
|
||||
#include <assert.h>
|
||||
#include <ion/src/device/shared/drivers/board.h>
|
||||
|
||||
#include <bootloader/boot.h>
|
||||
|
||||
void ion_main(int argc, const char * const argv[]) {
|
||||
__attribute__ ((noreturn)) void ion_main(int argc, const char * const argv[]) {
|
||||
// Clear the screen
|
||||
Ion::Display::pushRectUniform(KDRect(0,0,320,240), KDColorBlack);
|
||||
// Initialize the backlight
|
||||
Ion::Backlight::init();
|
||||
|
||||
// Set the mode to slot A if undefined
|
||||
if (Bootloader::Boot::mode() == Bootloader::BootMode::Unknown)
|
||||
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
|
||||
|
||||
// Handle rebooting to bootloader
|
||||
if (Bootloader::Boot::mode() == Bootloader::BootMode::SlotABootloader) {
|
||||
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
|
||||
Bootloader::Boot::bootloader();
|
||||
@@ -24,14 +25,17 @@ void ion_main(int argc, const char * const argv[]) {
|
||||
|
||||
uint64_t scan = Ion::Keyboard::scan();
|
||||
|
||||
// Reset+4 => Launch bootloader
|
||||
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Four)) {
|
||||
Bootloader::Boot::bootloader();
|
||||
// Reset+1 => Launch slot A
|
||||
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::One)) {
|
||||
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
|
||||
// Reset+2 => Launch slot B
|
||||
} else if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Two)) {
|
||||
Bootloader::Boot::setMode(Bootloader::BootMode::SlotB);
|
||||
}
|
||||
|
||||
Ion::Device::Board::bootloaderMPU();
|
||||
// Boot the firmware
|
||||
Bootloader::Boot::boot();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <bootloader/slot.h>
|
||||
#include <ion/src/device/shared/drivers/board.h>
|
||||
|
||||
extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));
|
||||
|
||||
@@ -21,8 +22,12 @@ const UserlandHeader* Slot::userlandHeader() const {
|
||||
}
|
||||
|
||||
[[ noreturn ]] void Slot::boot() const {
|
||||
// Configure the MPU for the booted firmware
|
||||
Ion::Device::Board::bootloaderMPU();
|
||||
|
||||
// Jump
|
||||
jump_to_firmware(kernelHeader()->stackPointer(), kernelHeader()->startPointer());
|
||||
for(;;);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user