[bootloader] Run usb stack on Reset+4

This commit is contained in:
M4x1m3
2022-02-25 23:23:47 +01:00
parent 4fe84a4959
commit e1dcbad18a
11 changed files with 165 additions and 26 deletions

View File

@@ -1,6 +1,16 @@
bootloader_src += $(addprefix bootloader/,\
main.cpp \
slot.cpp \
interface.cpp \
jump_to_firmware.s \
)
bootloader_src += $(ion_src) $(kandinsky_src) $(liba_src) $(libaxx_src)
bootloader_images = $(addprefix bootloader/, \
cable.png \
computer.png \
)
bootloader_src += $(ion_src) $(kandinsky_src) $(liba_src) $(libaxx_src) $(bootloader_images)
$(eval $(call depends_on_image,bootloader/interface.cpp,$(bootloader_images)))

47
bootloader/interface.cpp Normal file
View File

@@ -0,0 +1,47 @@
#include <assert.h>
#include <ion.h>
#include "interface.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();
drawImage(ctx, ImageStore::Computer, 70);
drawImage(ctx, ImageStore::Cable, 172);
}
}

22
bootloader/interface.h Normal file
View File

@@ -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

View File

@@ -0,0 +1,11 @@
.syntax unified
.section .text.jump_to_firmware
.align 2
.thumb
.global jump_to_firmware
jump_to_firmware:
dsb 0xF
isb 0xF
msr msp, r0
bx r1

View File

@@ -1,15 +1,32 @@
#include <ion/backlight.h>
#include <ion/display.h>
#include <ion/timing.h>
#include <ion.h>
#include <bootloader/slot.h>
#include <assert.h>
#include "interface.h"
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();
while (1) {
Ion::Display::pushRectUniform(KDRect(0,0,10,10), KDColorRed);
Ion::Timing::msleep(100);
Ion::Display::pushRectUniform(KDRect(0,0,10,10), KDColorBlue);
Ion::Timing::msleep(100);
uint64_t scan = Ion::Keyboard::scan();
if (scan == Ion::Keyboard::State(Ion::Keyboard::Key::Four)) {
Bootloader::Interface::draw();
while (true) {
Ion::USB::enable();
while (!Ion::USB::isEnumerated()) {
}
Ion::USB::DFU(false);
}
}
/*
KDContext * ctx = KDIonContext::sharedContext();
ctx->drawString(Bootloader::s_slotA->version(), KDPoint(0, 20));
*/
Bootloader::s_slotA->boot();
}

View File

@@ -1,8 +1,29 @@
#include <bootloader/slot.h>
extern "C" void jump_to_firmware(const uint32_t* stackPtr, const void(*startPtr)(void));
namespace Bootloader {
const struct Slot* s_slotA = reinterpret_cast<const struct Slot*>(0x90000000);
const struct Slot* s_slotB = reinterpret_cast<const struct Slot*>(0x90400000);
const Slot* s_slotA = reinterpret_cast<const struct Slot*>(0x90000000);
const Slot* s_slotB = reinterpret_cast<const struct Slot*>(0x90400000);
const char * Slot::version() const {
return m_version;
}
const char * Slot::patchLevel() const {
return m_patchLevel;
}
const bool Slot::isValid() const {
return m_header == Magic && m_footer == Magic;
}
[[ noreturn ]] void Slot::boot() const {
jump_to_firmware(m_stackPointer, m_startPointer);
for(;;);
}
}

View File

@@ -5,21 +5,29 @@
namespace Bootloader {
struct Slot {
uint32_t unknown;
uint32_t signature_offset;
uint32_t magik_header;
char version[8];
char patch_level[8];
uint32_t magik_footer;
uint32_t* stack_pointer;
void(*main_pointer)();
class Slot {
public:
const char * version() const;
const char * patchLevel() const;
const bool isValid() const;
[[ noreturn ]] void boot() const;
private:
Slot();
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)();
};
extern const struct Slot* s_slotA;
extern const struct Slot* s_slotB;
extern const Slot* s_slotA;
extern const Slot* s_slotB;
}
#endif
#endif

View File

@@ -6,7 +6,7 @@ $(BUILD_DIR)/test.external_flash.read.$(EXE): $(BUILD_DIR)/quiz/src/test_ion_ext
$(BUILD_DIR)/test.external_flash.write.$(EXE): $(BUILD_DIR)/quiz/src/test_ion_external_flash_write_symbols.o $(call object_for,$(test_external_flash_src) $(test_ion_external_flash_write_src))
$(BUILD_DIR)/bootloader.$(EXE): $(call flavored_object_for,$(bootloader_src))
$(BUILD_DIR)/bootloader.$(EXE): $(call flavored_object_for,$(bootloader_src),usbxip)
$(BUILD_DIR)/bootloader.$(EXE): LDSCRIPT = ion/test/device/n0110/external_flash_tests.ld
.PHONY: %_flash

View File

@@ -40,5 +40,8 @@
"apps/probability/images/normal_icon.png" : "probability/normal_icon.png",
"apps/probability/images/poisson_icon.png" : "probability/poisson_icon.png",
"apps/probability/images/student_icon.png" : "probability/student_icon.png",
"apps/probability/images/uniform_icon.png" : "probability/uniform_icon.png"
"apps/probability/images/uniform_icon.png" : "probability/uniform_icon.png",
"bootloader/cable.png": "bootloader/cable.png",
"bootloader/computer.png": "bootloader/computer.png"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB