forked from numworks/epsilon
-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
106 changed files
with
3,952 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
bootloader_src += $(addprefix bootloader/,\ | ||
boot.cpp \ | ||
main.cpp \ | ||
kernel_header.cpp \ | ||
userland_header.cpp \ | ||
slot.cpp \ | ||
interface.cpp \ | ||
jump_to_firmware.s \ | ||
trampoline.cpp \ | ||
usb_desc.cpp \ | ||
) | ||
|
||
bootloader_images = $(addprefix bootloader/, \ | ||
cable.png \ | ||
computer.png \ | ||
) | ||
|
||
bootloader_src += $(filter-out ion/src/device/shared/drivers/usb_desc.cpp,$(ion_src)) $(kandinsky_src) $(liba_src) $(libaxx_src) $(bootloader_images) | ||
|
||
$(eval $(call depends_on_image,bootloader/interface.cpp,$(bootloader_images))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include <bootloader/boot.h> | ||
#include <bootloader/slot.h> | ||
#include <ion.h> | ||
#include <ion/src/device/shared/drivers/reset.h> | ||
#include <bootloader/interface.h> | ||
|
||
#include <assert.h> | ||
|
||
namespace Bootloader { | ||
|
||
BootMode Boot::mode() { | ||
// We use the exam mode driver as storage for the boot mode | ||
uint8_t mode = Ion::ExamMode::FetchExamMode(); | ||
|
||
if (mode > 3) | ||
return Unknown; | ||
|
||
return (BootMode) mode; | ||
} | ||
|
||
void Boot::setMode(BootMode mode) { | ||
BootMode currentMode = Boot::mode(); | ||
if (currentMode == mode) | ||
return; | ||
|
||
assert(mode != BootMode::Unknown); | ||
int8_t deltaMode = (int8_t)mode - (int8_t)currentMode; | ||
deltaMode = deltaMode < 0 ? deltaMode + 4 : deltaMode; | ||
assert(deltaMode > 0); | ||
Ion::ExamMode::IncrementExamMode(deltaMode); | ||
} | ||
|
||
__attribute__((noreturn)) void Boot::boot() { | ||
assert(mode() != BootMode::Unknown); | ||
|
||
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(); | ||
} 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(); | ||
} | ||
|
||
__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); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef BOOTLOADER_BOOT_H | ||
#define BOOTLOADER_BOOT_H | ||
|
||
#include <stdint.h> | ||
|
||
namespace Bootloader { | ||
|
||
enum BootMode: uint8_t { | ||
SlotA = 0, | ||
SlotB = 1, | ||
// These modes exists so that you can launch the bootloader from a running slot | ||
// They mean "Launch bootloader then go back to slot X" | ||
SlotABootloader = 2, | ||
SlotBBootloader = 3, | ||
Unknown | ||
}; | ||
|
||
class Boot { | ||
public: | ||
static BootMode mode(); | ||
static void setMode(BootMode mode); | ||
__attribute__ ((noreturn)) static void boot(); | ||
__attribute__ ((noreturn)) static void bootloader(); | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
|
||
#include <assert.h> | ||
#include <ion.h> | ||
|
||
#include <bootloader/interface.h> | ||
#include <bootloader/slot.h> | ||
#include <bootloader/boot.h> | ||
|
||
#include "computer.h" | ||
#include "cable.h" | ||
|
||
namespace Bootloader { | ||
|
||
void Interface::drawImage(KDContext* ctx, const Image* image, int offset) { | ||
const uint8_t* data; | ||
size_t size; | ||
size_t pixelBufferSize; | ||
|
||
if (image != nullptr) { | ||
data = image->compressedPixelData(); | ||
size = image->compressedPixelDataSize(); | ||
pixelBufferSize = image->width() * image->height(); | ||
} else { | ||
return; | ||
} | ||
|
||
KDColor pixelBuffer[4000]; | ||
assert(pixelBufferSize <= 4000); | ||
assert(Ion::stackSafe()); // That's a VERY big buffer we're allocating on the stack | ||
|
||
Ion::decompress( | ||
data, | ||
reinterpret_cast<uint8_t *>(pixelBuffer), | ||
size, | ||
pixelBufferSize * sizeof(KDColor) | ||
); | ||
|
||
KDRect bounds((320 - image->width()) / 2, offset, image->width(), image->height()); | ||
|
||
ctx->fillRectWithPixels(bounds, pixelBuffer, nullptr); | ||
} | ||
|
||
void Interface::draw() { | ||
KDContext * ctx = KDIonContext::sharedContext(); | ||
ctx->fillRect(KDRect(0,0,320,240), KDColorBlack); | ||
drawImage(ctx, ImageStore::Computer, 70); | ||
drawImage(ctx, ImageStore::Cable, 172); | ||
|
||
ctx->drawString("Slot A:", KDPoint(0, 0), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
ctx->drawString("Slot B:", KDPoint(0, 13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
ctx->drawString("Current:", KDPoint(0, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
|
||
if (Boot::mode() == BootMode::SlotA) { | ||
ctx->drawString("Slot A", KDPoint(63, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
} else if (Boot::mode() == BootMode::SlotB) { | ||
ctx->drawString("Slot B", KDPoint(63, 26), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
} | ||
|
||
Slot slots[2] = {Slot::A(), Slot::B()}; | ||
|
||
for(uint8_t i = 0; i < 2; i++) { | ||
Slot slot = slots[i]; | ||
|
||
if (slot.kernelHeader()->isValid() && slot.userlandHeader()->isValid()) { | ||
if (slot.userlandHeader()->isOmega() && slot.userlandHeader()->isUpsilon()) { | ||
ctx->drawString("Upsilon", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
ctx->drawString(slot.userlandHeader()->upsilonVersion(), KDPoint(112, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
} else if (slot.userlandHeader()->isOmega()) { | ||
ctx->drawString("Omega", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
ctx->drawString(slot.userlandHeader()->omegaVersion(), KDPoint(112, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
} else { | ||
ctx->drawString("Epsilon", KDPoint(56, i*13), KDFont::SmallFont, KDColorWhite, KDColorBlack); | ||
ctx->drawString(slot.userlandHeader()->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); | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#ifndef BOOTLOADER_INTERFACE | ||
#define BOOTLOADER_INTERFACE | ||
|
||
#include <stdint.h> | ||
#include <kandinsky/context.h> | ||
#include <escher/image.h> | ||
|
||
namespace Bootloader { | ||
|
||
class Interface { | ||
|
||
private: | ||
static void drawImage(KDContext* ctx, const Image* image, int offset); | ||
|
||
public: | ||
static void draw(); | ||
|
||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
.syntax unified | ||
.section .text.jump_to_firmware | ||
.align 2 | ||
.thumb | ||
.global jump_to_firmware | ||
jump_to_firmware: | ||
msr msp, r0 | ||
bx r1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <bootloader/kernel_header.h> | ||
|
||
namespace Bootloader { | ||
|
||
const char * KernelHeader::version() const { | ||
return m_version; | ||
} | ||
|
||
const char * KernelHeader::patchLevel() const { | ||
return m_patchLevel; | ||
} | ||
|
||
const bool KernelHeader::isValid() const { | ||
return m_header == Magic && m_footer == Magic; | ||
} | ||
|
||
const uint32_t* KernelHeader::stackPointer() const { | ||
return m_stackPointer; | ||
} | ||
|
||
const void(*KernelHeader::startPointer() const)() { | ||
return m_startPointer; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef BOOTLOADER_KERNEL_HEADER_H | ||
#define BOOTLOADER_KERNEL_HEADER_H | ||
|
||
#include <stdint.h> | ||
|
||
namespace Bootloader { | ||
|
||
class KernelHeader { | ||
public: | ||
const char * version() const; | ||
const char * patchLevel() const; | ||
const bool isValid() const; | ||
|
||
const uint32_t* stackPointer() const; | ||
const void(*startPointer() const)(); | ||
|
||
private: | ||
KernelHeader(); | ||
constexpr static uint32_t Magic = 0xDEC00DF0; | ||
const uint32_t m_unknown; | ||
const uint32_t m_signature; | ||
const uint32_t m_header; | ||
const char m_version[8]; | ||
const char m_patchLevel[8]; | ||
const uint32_t m_footer; | ||
const uint32_t* m_stackPointer; | ||
const void(*m_startPointer)(); | ||
}; | ||
|
||
} | ||
|
||
#endif |
Oops, something went wrong.