diff --git a/alt.lds b/alt.lds index 571618e..ccd8937 100644 --- a/alt.lds +++ b/alt.lds @@ -1,7 +1,8 @@ OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") MEMORY { - p1ram : ORIGIN = 0x8c020000, LENGTH = 0xff0000 - p2ram : ORIGIN = 0xac020000, LENGTH = 0xff0000 + p1ram : ORIGIN = 0x8c020000, LENGTH = 0xfe0000 + p2ram : ORIGIN = 0xac020000, LENGTH = 0xfe0000 } +__stack_reservation = 0x1000; INCLUDE "common.lds" diff --git a/client.py b/client.py index a26f832..07a4055 100644 --- a/client.py +++ b/client.py @@ -70,7 +70,11 @@ def do(ser, b): sync(ser, b'prime', wait=0) do(ser, b) print("\nDATA") + start = time.monotonic() ret = symmetric(ser, b) + end = time.monotonic() + duration = end - start + print("duration", duration) print(ret[-5:]) if ret[:-5] != b: print("ret != b; dumped to asdf.bin") @@ -96,8 +100,8 @@ def console(ser): with open(sys.argv[1], 'rb') as f: b = f.read() -#with serial.Serial('/dev/ttyUSB0', 120192, timeout=1) as ser: -with serial.Serial('/dev/ttyUSB0', 312500, timeout=1) as ser: +with serial.Serial('/dev/ttyUSB0', 120192, timeout=1) as ser: +#with serial.Serial('/dev/ttyUSB0', 312500, timeout=1) as ser: #console(ser) print("waiting: ", end=' ') sys.stdout.flush() diff --git a/common.lds b/common.lds index 0cdaac2..0f36d99 100644 --- a/common.lds +++ b/common.lds @@ -44,13 +44,5 @@ SECTIONS INCLUDE "debug.lds" } -__p1ram_start = ORIGIN(p1ram); -__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram); - -__bss_link_start = ADDR(.bss); -__bss_link_end = ADDR(.bss) + SIZEOF(.bss); - -__ctors_link_start = ADDR(.ctors); -__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); - +INCLUDE "symbols.lds" INCLUDE "addresses.lds" diff --git a/common.mk b/common.mk index 6dba415..bcef840 100644 --- a/common.mk +++ b/common.mk @@ -2,7 +2,7 @@ MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) DIR := $(dir $(MAKEFILE_PATH)) LIB ?= . -OPT ?= -O3 +OPT ?= -Og GENERATED ?= AARCH = --isa=sh4 --little @@ -32,6 +32,11 @@ IP_OBJ = \ sg/sg_ini.o \ sg/aip.o +%.o: %.obj + $(OBJCOPY) -g \ + --rename-section IP=.text.$* \ + $< $@ + ip.elf: $(IP_OBJ) $(LD) --orphan-handling=error --print-memory-usage -T $(LIB)/ip.lds $^ -o $@ @@ -42,11 +47,6 @@ START_OBJ = \ include base.mk -%.o: %.obj - $(OBJCOPY) -g \ - --rename-section IP=.text.$* \ - $< $@ - sine.pcm: common.mk sox \ --rate 44100 \ diff --git a/example/example.mk b/example/example.mk index e90640a..3dd3627 100644 --- a/example/example.mk +++ b/example/example.mk @@ -16,7 +16,9 @@ SPRITE_OBJ = \ holly/core.o \ holly/region_array.o \ holly/background.o \ - holly/ta_fifo_polygon_converter.o + holly/ta_fifo_polygon_converter.o \ + sh7091/serial.o \ + $(LIBGCC) example/sprite.elf: LDSCRIPT = $(LIB)/alt.lds example/sprite.elf: $(START_OBJ) $(SPRITE_OBJ) @@ -149,7 +151,7 @@ WIFFLE_ATTENUATION_OBJ = \ holly/background.o \ holly/ta_fifo_polygon_converter.o -example/wiffle_attenuation.elf: LDSCRIPT = $(LIB)/alt.lds +example/wiffle_attenuation.elf: LDSCRIPT = $(LIB)/main.lds example/wiffle_attenuation.elf: $(START_OBJ) $(WIFFLE_ATTENUATION_OBJ) MODIFIER_VOLUME_OBJ = \ @@ -322,7 +324,7 @@ SERIAL_TRANSFER_OBJ = \ sh7091/serial.o \ serial_load.o -example/serial_transfer.elf: LDSCRIPT = $(LIB)/main.lds +example/serial_transfer.elf: LDSCRIPT = $(LIB)/loader.lds example/serial_transfer.elf: $(START_OBJ) $(SERIAL_TRANSFER_OBJ) INTERRUPT_OBJ = \ diff --git a/example/macaw.cpp b/example/macaw.cpp index e90eb53..42a4bed 100644 --- a/example/macaw.cpp +++ b/example/macaw.cpp @@ -185,5 +185,8 @@ void main() theta += half_degree; frame_ix += 1; + + if (frame_ix > 10) + break; } } diff --git a/example/serial_transfer.cpp b/example/serial_transfer.cpp index c95b6c6..5c05424 100644 --- a/example/serial_transfer.cpp +++ b/example/serial_transfer.cpp @@ -6,24 +6,19 @@ #include "serial_load.hpp" -extern uint32_t __bss_link_start __asm("__bss_link_start"); -extern uint32_t __bss_link_end __asm("__bss_link_end"); +void main() __attribute__((section(".text.main"))); void main() { - serial::init(4); + //serial::init(12); load_init(); while (1) { using namespace scif; - while ((sh7091.SCIF.SCFSR2 & scfsr2::tdfe::bit_mask) == 0) { - // wait - } while ((scfdr2::receive_data_bytes(sh7091.SCIF.SCFDR2)) > 0) { - uint8_t c = sh7091.SCIF.SCFRDR2; + const uint8_t c = sh7091.SCIF.SCFRDR2; load_recv(c); } - sh7091.SCIF.SCFSR2 = sh7091.SCIF.SCFSR2 & (~scfsr2::rdf::bit_mask); } } diff --git a/loader.lds b/loader.lds new file mode 100644 index 0000000..601e03b --- /dev/null +++ b/loader.lds @@ -0,0 +1,61 @@ +OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") +MEMORY +{ + p1ram : ORIGIN = 0x8c020000, LENGTH = 0xfe0000 + p2ram : ORIGIN = 0xac020000, LENGTH = 0xfe0000 + ldram : ORIGIN = 0x8cfff000, LENGTH = 0x1000 +} +SECTIONS +{ + . = ORIGIN(p2ram); + + .text.startup ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.start)) + *(.text.startup.*) + . = ALIGN(4); + } > p2ram AT> p2ram + + .ctors ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + . = ALIGN(4); + } > p2ram AT> p2ram + + . = ORIGIN(ldram); + + .text ALIGN(4) : SUBALIGN(4) + { + *(.text.*) + *(.text) + . = ALIGN(4); + } > ldram AT> p2ram + + .data ALIGN(4) : SUBALIGN(4) + { + *(.data) + *(.data.*) + . = ALIGN(4); + } > ldram AT> p2ram + + .rodata ALIGN(4) : SUBALIGN(4) + { + *(.rodata) + *(.rodata.*) + . = ALIGN(4); + } > ldram AT> p2ram + + .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + { + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + } > ldram + + INCLUDE "debug.lds" +} +__stack_reservation = 0x0000; +INCLUDE "symbols.lds" +INCLUDE "addresses.lds" diff --git a/main.lds b/main.lds index 70cfe91..94bfbc3 100644 --- a/main.lds +++ b/main.lds @@ -4,4 +4,5 @@ MEMORY p1ram : ORIGIN = 0x8c010000, LENGTH = 0xff0000 p2ram : ORIGIN = 0xac010000, LENGTH = 0xff0000 } +__stack_reservation = 0x1000; INCLUDE "common.lds" diff --git a/runtime.cpp b/runtime.cpp index 6460fe8..55a0fd7 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -1,27 +1,76 @@ #include +#include #include "sh7091/cache.hpp" +#include "string.hpp" + +extern uint32_t __text_link_start __asm("__text_link_start"); +extern uint32_t __text_link_end __asm("__text_link_end"); +extern uint32_t __text_load_start __asm("__text_load_start"); + +extern uint32_t __data_link_start __asm("__data_link_start"); +extern uint32_t __data_link_end __asm("__data_link_end"); +extern uint32_t __data_load_start __asm("__data_load_start"); + +extern uint32_t __rodata_link_start __asm("__rodata_link_start"); +extern uint32_t __rodata_link_end __asm("__rodata_link_end"); +extern uint32_t __rodata_load_start __asm("__rodata_load_start"); + +extern uint32_t __ctors_link_start __asm("__ctors_link_start"); +extern uint32_t __ctors_link_end __asm("__ctors_link_end"); + extern uint32_t __bss_link_start __asm("__bss_link_start"); extern uint32_t __bss_link_end __asm("__bss_link_end"); extern void main(); +typedef void(init_t)(void); + extern "C" void runtime_init() __attribute__((section(".text.startup.runtime_init"))); +void copy(uint32_t * start, const uint32_t * end, uint32_t * load) +__attribute__((section(".text.startup.copy"))); + +void copy(uint32_t * start, const uint32_t * end, uint32_t * load) +{ + if (start != load) { + while (start < end) { + *start++ = *load++; + } + } +} + extern "C" void runtime_init() { + // relocate text (if necessary) + copy(&__text_link_start, &__text_link_end, &__text_load_start); + + // relocate data (if necessary) + copy(&__data_link_start, &__data_link_end, &__data_load_start); + + // relocate rodata (if necessary) + copy(&__rodata_link_start, &__rodata_link_end, &__rodata_load_start); + + uint32_t * start; + uint32_t * end; + // clear BSS - uint32_t * start = &__bss_link_start; - uint32_t * end = &__bss_link_end; + start = &__bss_link_start; + end = &__bss_link_end; while (start < end) { *start++ = 0; } - cache::init(); + // call ctors + start = &__ctors_link_start; + end = &__ctors_link_end; + while (start < end) { + ((init_t*)(*start++))(); + } - main(); + cache::init(); } diff --git a/serial_load.cpp b/serial_load.cpp index d76564c..f4be31b 100644 --- a/serial_load.cpp +++ b/serial_load.cpp @@ -2,6 +2,7 @@ #include "sh7091/sh7091.hpp" #include "sh7091/sh7091_bits.hpp" +#include "sh7091/serial.hpp" #include "holly/holly.hpp" enum load_command { @@ -54,6 +55,24 @@ void debug(const char * s) } } +void jump_to_func(const uint32_t addr) +{ + serial::string("jump to: "); + serial::integer(addr); + // save our stack + asm volatile ("ldc r15, gbr; " + "mov #0, r15; " + "jsr @%0; " + "nop; " + "stc gbr, r15; " + : + : "r"(addr) /* input */ + /* clobbered register */ + : "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","macl","mach","gbr","pr" + ); + // restore our stack +} + void load_recv(uint8_t c) { if (state.command == CMD_NONE) @@ -119,8 +138,7 @@ void load_recv(uint8_t c) state.command = CMD_NONE; debug("prejump\n"); holly.VO_BORDER_COL = (31 << 11); - void (*fptr)(void) = (void (*)(void))state.addr1; - fptr(); + jump_to_func(state.addr1); holly.VO_BORDER_COL = (63 << 5) | (31 << 0); debug("postjump\n"); return; diff --git a/sh7091/serial.cpp b/sh7091/serial.cpp index ca8361e..cc4073a 100644 --- a/sh7091/serial.cpp +++ b/sh7091/serial.cpp @@ -19,11 +19,20 @@ void init(uint8_t bit_rate) sh7091.SCIF.SCFCR2 = scfcr2::tfrst::reset_operation_enabled | scfcr2::rfrst::reset_operation_enabled; - // tx/rx trigger on 1 byte - sh7091.SCIF.SCFCR2 = 0; + + sh7091.SCIF.SCFCR2 = scfcr2::rtrg::trigger_on_1_byte + | scfcr2::ttrg::trigger_on_8_bytes + | scfcr2::mce::modem_signals_disabled; sh7091.SCIF.SCSPTR2 = 0; - sh7091.SCIF.SCLSR2 = 0; + sh7091.SCIF.SCFSR2 = (~scfsr2::er::bit_mask) + & (~scfsr2::tend::bit_mask) + & (~scfsr2::tdfe::bit_mask) + & (~scfsr2::brk::bit_mask) + & (~scfsr2::rdf::bit_mask) + & (~scfsr2::dr::bit_mask) + & 0xffff; + sh7091.SCIF.SCLSR2 = 0; // clear ORER sh7091.SCIF.SCSCR2 = scscr2::te::transmission_enabled | scscr2::re::reception_enabled; diff --git a/start.s b/start.s index 2268c9b..fe70eb7 100644 --- a/start.s +++ b/start.s @@ -10,11 +10,22 @@ _start: or r1,r0 ldc r0,sr + /* save pr */ + sts.l pr,@-r15 + /* jump to runtime_init */ mov.l runtime_init_ptr,r0 - jmp @r0 + jsr @r0 nop + /* restore pr */ + lds.l @r15+,pr + + /* jump to main */ + mov.l main_ptr,r0 + jmp @r0 + nop + .align 4 p1ram_end_ptr: .long __p1ram_end @@ -22,3 +33,5 @@ imask_all: .long 0xf0 runtime_init_ptr: .long _runtime_init +main_ptr: + .long _main diff --git a/symbols.lds b/symbols.lds new file mode 100644 index 0000000..02f1ea8 --- /dev/null +++ b/symbols.lds @@ -0,0 +1,21 @@ +__p1ram_start = ORIGIN(p1ram); +/* reserve bytes for serial program loader */ +__p1ram_end = ORIGIN(p1ram) + LENGTH(p1ram) - __stack_reservation; + +__text_link_start = ADDR(.text); +__text_link_end = ADDR(.text) + SIZEOF(.text); +__text_load_start = LOADADDR(.text); + +__data_link_start = ADDR(.data); +__data_link_end = ADDR(.data) + SIZEOF(.data); +__data_load_start = LOADADDR(.data); + +__rodata_link_start = ADDR(.rodata); +__rodata_link_end = ADDR(.rodata) + SIZEOF(.rodata); +__rodata_load_start = LOADADDR(.rodata); + +__ctors_link_start = ADDR(.ctors); +__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); + +__bss_link_start = ADDR(.bss); +__bss_link_end = ADDR(.bss) + SIZEOF(.bss);