From d568f7ca9d7bf2d9dbf0b58d011ae8693ed6703e Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 29 Aug 2020 19:58:08 -0400 Subject: [PATCH] improved elf loading --- cfg/chconf.h | 3 +++ gui/wxmain.cpp | 36 +++++++++++++++++++++--------------- source/elf_load.cpp | 24 ++++++++++-------------- source/main.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 30 deletions(-) diff --git a/cfg/chconf.h b/cfg/chconf.h index 53b3224..eb399f7 100644 --- a/cfg/chconf.h +++ b/cfg/chconf.h @@ -751,6 +751,9 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ +// Enable syscall support +#define PORT_USE_SYSCALL TRUE + #endif /* CHCONF_H */ /** @} */ diff --git a/gui/wxmain.cpp b/gui/wxmain.cpp index c2a378a..fa9118d 100644 --- a/gui/wxmain.cpp +++ b/gui/wxmain.cpp @@ -181,18 +181,13 @@ void MainFrame::prepareEditor() static const char *makefile_text = R"make( all: - @arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE -c $0 -o $0.o - @arm-none-eabi-ld -shared -n -N -z max-page-size=512 -Ttext-segment=0 \ - $0.o -o $0.so - @arm-none-eabi-strip -s -S --strip-unneeded $0.so - @arm-none-eabi-objcopy --remove-section .dynsym \ - --remove-section .dynstr \ - --remove-section .dynamic \ - --remove-section .hash \ - --remove-section .ARM.exidx \ - --remove-section .ARM.attributes \ - --remove-section .comment \ - $0.so + @arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE $0 -o $0.o -Wl,-Ttext-segment=0 -Wl,-eprocess_data_entry -Wl,-zmax-page-size=512 + @arm-none-eabi-strip -s -S --strip-unneeded $0.o + @arm-none-eabi-objcopy --remove-section .ARM.exidx \ + --remove-section .ARM.attributes \ + --remove-section .comment \ + --remove-section .noinit \ + $0.o )make"; static const char *file_header = R"cpp( @@ -200,10 +195,21 @@ static const char *file_header = R"cpp( using adcsample_t = uint16_t; -__attribute__((section(".process_data"))) void process_data(adcsample_t *samples, unsigned int size); +static void process_data(adcsample_t *samples, unsigned int size); -// End stmdspgui header code +__attribute__((optimize("-O0"))) +static void *alloc(unsigned int count) { + void *result = nullptr; + asm("mov r0, %0; mov r1, %1; svc 0" :: "r" (&result), "r" (count)); + return result; +} +extern "C" void process_data_entry() { + auto func = (void (*)())process_data; + func(); +} + +// End stmdspgui header code )cpp"; wxString MainFrame::compileEditorCode() @@ -223,7 +229,7 @@ wxString MainFrame::compileEditorCode() wxString make_command = wxString("make -C ") + file_name.BeforeLast('/') + " -f " + file_name + "make"; if (system(make_command.ToAscii()) == 0) - return file_name + ".so"; + return file_name + ".o"; else return ""; } diff --git a/source/elf_load.cpp b/source/elf_load.cpp index 8149e8a..161bd7e 100644 --- a/source/elf_load.cpp +++ b/source/elf_load.cpp @@ -54,29 +54,25 @@ entry_t load(void *elf_data, void *elf_load_offset) // [elf_load_offset](auto func) { (func + elf_load_offset)(); }); //} - // Find filter code start - if (auto filter = find_section(ehdr, ".process_data"); filter) - return ptr_from_offset(elf_load_offset, filter->sh_addr | 1); // OR 1 to enable thumb - else - return nullptr; + return ptr_from_offset(elf_load_offset, ehdr->e_entry); } } // namespace elf Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name) { - auto shdr = ptr_from_offset(ehdr, ehdr->e_shoff); - auto shdr_str = ptr_from_offset(ehdr, + auto shdr = ptr_from_offset(ehdr, ehdr->e_shoff); + auto shdr_str = ptr_from_offset(ehdr, ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize); - for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) { - char *section = ptr_from_offset(ehdr, shdr_str->sh_offset) + shdr->sh_name; - if (!strcmp(section, name)) - return shdr; + for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) { + char *section = ptr_from_offset(ehdr, shdr_str->sh_offset) + shdr->sh_name; + if (!strcmp(section, name)) + return shdr; - shdr = ptr_from_offset(shdr, ehdr->e_shentsize); - } + shdr = ptr_from_offset(shdr, ehdr->e_shentsize); + } - return 0; + return 0; } diff --git a/source/main.cpp b/source/main.cpp index 6c418ce..4bdd5a2 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -111,12 +111,52 @@ int main() } } +void quick_freeall(); + void signal_operate(adcsample_t *buffer, size_t count) { - if (elf_entry) + if (elf_entry) { elf_entry(buffer, count); + quick_freeall(); + } + auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024]; std::copy(buffer, buffer + count, dac_buffer); signal_operate_done = buffer == &adc_samples[1024]; } +// Dynamic memory allocation below + +uint8_t quick_malloc_heap[8192]; +uint8_t *quick_malloc_next = quick_malloc_heap; + +void *quick_malloc(unsigned int size) +{ + if (auto free = std::distance(quick_malloc_next, quick_malloc_heap + 8192); free < 0 || size > static_cast(free)) + return nullptr; + + auto ptr = quick_malloc_next; + quick_malloc_next += size; + return ptr; +} + +void quick_freeall() +{ + if (quick_malloc_next != quick_malloc_heap) + quick_malloc_next = quick_malloc_heap; +} + +void port_syscall(struct port_extctx *ctxp, uint32_t n) +{ + switch (n) { + case 0: + *reinterpret_cast(ctxp->r0) = quick_malloc(ctxp->r1); + break; + case 1: + quick_freeall(); + break; + } + + chSysHalt("svc"); +} +