Skip to content

Commit

Permalink
Merge pull request #593 from Lisra-git/omega-dev
Browse files Browse the repository at this point in the history
E20 and QOL
  • Loading branch information
M4xi1m3 authored Dec 28, 2022
2 parents d0308f8 + 7593b3b commit d5e0174
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 158 deletions.
97 changes: 67 additions & 30 deletions bootloader/boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,29 @@ __attribute__((noreturn)) void Boot::boot() {
} else if (!Slot::A().kernelHeader()->isValid()) {
// If slot A is invalid and B valid, boot B
setMode(BootMode::SlotB);
Slot::B().boot();
Slot::B().boot("B");
} else if (!Slot::B().kernelHeader()->isValid()) {
// If slot B is invalid and A valid, boot A
setMode(BootMode::SlotA);
Slot::A().boot();
Slot::A().boot("A");
} else {

Bootloader::ExamMode::ExamMode SlotAExamMode = (Bootloader::ExamMode::ExamMode)Bootloader::ExamMode::SlotsExamMode::FetchSlotAExamMode(!Bootloader::Slot::A().userlandHeader()->isOmega());
if (SlotAExamMode != Bootloader::ExamMode::ExamMode::Off && SlotAExamMode != Bootloader::ExamMode::ExamMode::Unknown) {
// We boot the slot in exam_mode
Bootloader::Slot::A().boot();
}
const char* version = Bootloader::Slot::A().kernelHeader()->version();
bool isExam = Bootloader::ExamMode::SlotsExamMode::FetchSlotExamMode(version, "A") > 0;
if (isExam) {
Bootloader::Slot::A().boot("A");
}

Bootloader::ExamMode::ExamMode SlotBExamMode = (Bootloader::ExamMode::ExamMode)Bootloader::ExamMode::SlotsExamMode::FetchSlotBExamMode(!Bootloader::Slot::B().userlandHeader()->isOmega());
if (SlotBExamMode != Bootloader::ExamMode::ExamMode::Off && SlotBExamMode != Bootloader::ExamMode::ExamMode::Unknown) {
// We boot the slot in exam_mode
Bootloader::Slot::B().boot();
}
version = Bootloader::Slot::B().kernelHeader()->version();
isExam = Bootloader::ExamMode::SlotsExamMode::FetchSlotExamMode(version, "B") > 0;
if (isExam) {
Bootloader::Slot::B().boot("B");
}

// Both valid, boot the selected one
if (mode() == BootMode::SlotA) {
Slot::A().boot();
Slot::A().boot("A");
} else if (mode() == BootMode::SlotB) {
Slot::B().boot();
Slot::B().boot("B");
}
}

Expand All @@ -74,21 +73,59 @@ __attribute__ ((noreturn)) void Boot::bootloader() {
for(;;) {
// Draw the interfaces and infos
Bootloader::Interface::draw();

// Enable USB
Ion::USB::enable();

// Wait for the device to be enumerated
do {
// If we pressed back while waiting, reset.
uint64_t scan = Ion::Keyboard::scan();
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Back)) {
Ion::Device::Reset::core();
}
} while (!Ion::USB::isEnumerated());

// Launch the DFU stack, allowing to press Back to quit and reset
Ion::USB::DFU(true);
Bootloader::Interface::drawMessageBox("Press (1)/(2) to select slot", "Press Power to reset");

bool abortUSB = false;
while (1) {
uint64_t scan = Ion::Keyboard::scan();
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::OnOff)) {
Ion::Device::Reset::core();
}
//allow to set bootmode with 1 and 2
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::One)) {
Bootloader::Boot::setMode(Bootloader::BootMode::SlotA);
Bootloader::Interface::draw();
Bootloader::Interface::drawMessageBox("Press (1)/(2) to select slot", "Press Power to reset");
Ion::Timing::msleep(100);
}
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Two)) {
Bootloader::Boot::setMode(Bootloader::BootMode::SlotB);
Bootloader::Interface::draw();
Bootloader::Interface::drawMessageBox("Press (1)/(2) to select slot", "Press Power to reset");
Ion::Timing::msleep(100);
}

if (Ion::USB::isPlugged() && !abortUSB) {
// Enable USB
Ion::USB::enable();

Bootloader::Interface::drawMessageBox("USB Enabled", "Press Back to disable USB");
// Launch the DFU stack, allowing to press Back to quit and reset
Ion::USB::DFU(true);
//wait for usb to be unplugged or back to be pressed
while (Ion::USB::isPlugged() && scan != Ion::Keyboard::State(Ion::Keyboard::Key::Back)) {
scan = Ion::Keyboard::scan();
Ion::Timing::msleep(100);
}
//cehck if usb is plugged
if (Ion::USB::isPlugged()) {
abortUSB = true;
}
// Disable USB
Ion::USB::disable();
Bootloader::Interface::draw();
Bootloader::Interface::drawMessageBox("Press (1)/(2) to select slot", "Press Power to reset");

}

//Prevent USB from launching after Back press
if (!Ion::USB::isPlugged() && abortUSB) {
abortUSB = false;
}

Ion::Timing::msleep(100);

}
}
}

Expand Down
40 changes: 31 additions & 9 deletions bootloader/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@

namespace Bootloader {

void Interface::drawMessageBox(const char* line1, const char* line2) {
KDContext* ctx = KDIonContext::sharedContext();
//draw a red box at bottom of screen
ctx->fillRect(KDRect(0, 210, 320, 32), KDColorRed);
//get lenght of each line
int line1Length = strlen(line1);
int line2Length = strlen(line2);
//draw the message
ctx->drawString(line1, KDPoint(160-((line1Length*8)/2), 210), KDFont::SmallFont, KDColorWhite, KDColorRed);
ctx->drawString(line2, KDPoint(160 - ((line2Length*8)/ 2), 228), KDFont::SmallFont, KDColorWhite, KDColorRed);

}

void Interface::drawImage(KDContext* ctx, const Image* image, int offset) {
const uint8_t* data;
size_t size;
Expand Down Expand Up @@ -74,23 +87,32 @@ void Interface::draw() {
}
ctx->drawString(slot.kernelHeader()->patchLevel(), KDPoint(168, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
} else {
ctx->drawString("Invalid", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
if (slot.userland2Header()->isValid()) {
ctx->drawString("Epsilon", KDPoint(56, i * 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
ctx->drawString(slot.userland2Header()->version(), KDPoint(112, i * 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
ctx->drawString(slot.kernelHeader()->patchLevel(), KDPoint(168, i * 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
else {
ctx->drawString("Invalid", KDPoint(56, i * 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
}

}

if (Bootloader::Slot::A().kernelHeader()->isValid()) {
Bootloader::ExamMode::ExamMode SlotAExamMode = (Bootloader::ExamMode::ExamMode)Bootloader::ExamMode::SlotsExamMode::FetchSlotAExamMode(!Bootloader::Slot::A().userlandHeader()->isOmega());
if (SlotAExamMode != Bootloader::ExamMode::ExamMode::Off && SlotAExamMode != Bootloader::ExamMode::ExamMode::Unknown) {
ctx->drawString("E", KDPoint(238, 0), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
const char* version = Bootloader::Slot::A().kernelHeader()->version();
bool isExam = Bootloader::ExamMode::SlotsExamMode::FetchSlotExamMode(version, "A") > 0;
if (isExam) {
ctx->drawString("E", KDPoint(238, 0), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
}

if (Bootloader::Slot::B().kernelHeader()->isValid()) {
Bootloader::ExamMode::ExamMode SlotBExamMode = (Bootloader::ExamMode::ExamMode)Bootloader::ExamMode::SlotsExamMode::FetchSlotBExamMode(!Bootloader::Slot::B().userlandHeader()->isOmega());
if (SlotBExamMode != Bootloader::ExamMode::ExamMode::Off && SlotBExamMode != Bootloader::ExamMode::ExamMode::Unknown) {
ctx->drawString("E", KDPoint(238, 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
const char* version = Bootloader::Slot::B().kernelHeader()->version();
bool isExam = Bootloader::ExamMode::SlotsExamMode::FetchSlotExamMode(version, "B") > 0;
if (isExam) {
ctx->drawString("E", KDPoint(238, 13), KDFont::SmallFont, KDColorWhite, KDColorBlack);
}
}

}
Expand Down
1 change: 1 addition & 0 deletions bootloader/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Interface {

public:
static void draw();
static void drawMessageBox(const char* line1, const char* line2);

};

Expand Down
26 changes: 25 additions & 1 deletion bootloader/slot.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <bootloader/slot.h>
#include <ion/src/device/shared/drivers/board.h>
#include <ion/src/device/shared/drivers/external_flash.h>
#include <bootloader/interface.h>

extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));

Expand All @@ -21,7 +23,29 @@ const UserlandHeader* Slot::userlandHeader() const {
return m_userlandHeader;
}

[[ noreturn ]] void Slot::boot() const {
const UserlandHeader* Slot::userland2Header() const {
return m_userland2Header;
}

[[ noreturn ]] void Slot::boot(const char* Slot) const {
//protection mechanism against bootloader update introduced in E20
//check if the slot use Userland2Header
if (m_userland2Header->isValid()) {
if (Slot == "A") {
//check if 0x90010000 = 0xFFFFFFFF
if (*(uint32_t*)0x90010000 != 0xFFFFFFFF) {
Ion::Device::ExternalFlash::EraseSector(9);
}
}
else if (Slot == "B") {
//check if 0x90410000 = 0xFFFFFFFF
if (*(uint32_t*)0x90410000 != 0xFFFFFFFF) {
Ion::Device::ExternalFlash::EraseSector(73);
}

}

}
// Configure the MPU for the booted firmware
Ion::Device::Board::bootloaderMPU();

Expand Down
7 changes: 5 additions & 2 deletions bootloader/slot.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@ class Slot {
public:
Slot(uint32_t address) :
m_kernelHeader(reinterpret_cast<KernelHeader*>(address)),
m_userlandHeader(reinterpret_cast<UserlandHeader*>(address + 64 * 1024)) { }
m_userlandHeader(reinterpret_cast<UserlandHeader*>(address + 64 * 1024)),
m_userland2Header(reinterpret_cast<UserlandHeader*>(address + 128 * 1024)) { }

const KernelHeader* kernelHeader() const;
const UserlandHeader* userlandHeader() const;
[[ noreturn ]] void boot() const;
const UserlandHeader* userland2Header() const;
[[ noreturn ]] void boot(const char* Slot) const;

static const Slot A();
static const Slot B();

private:
const KernelHeader* m_kernelHeader;
const UserlandHeader* m_userlandHeader;
const UserlandHeader* m_userland2Header;

};

Expand Down
Loading

0 comments on commit d5e0174

Please sign in to comment.