diff --git a/bootloader.c b/bootloader.c index 56c7854..7d2438e 100644 --- a/bootloader.c +++ b/bootloader.c @@ -380,20 +380,16 @@ __attribute__((naked)) int main(void) { ACTIVE_CONFIG = 0; const uint8_t *outputting_desc = 0; CTRL_XFER_DESC_SZ = 0; + ADDRESS_HI = 0; // bits [31:24] = additional sense code // bits [23:20] = sense key // bits [7:0] = state uint32_t msc_state = STATE_WANT_CBW; - // when reading: - // [31:16] = current lba - // [15:0] = blocks left - // when writing: - // [31:16] = ignored - // [15:0] = blocks left UF2_GOT_BLOCKS[35] = 0; + while (1) { uint32_t usb_int_status = R16_USBD_ISTR; if (usb_int_status & (1 << 10)) { @@ -849,7 +845,6 @@ __attribute__((naked)) int main(void) { msc_state = (msc_state & 0xffffff00) | STATE_WANT_CBW; break; case STATE_SENT_CSW_REBOOT: - // todo reboot into ram STK_CMPLR = (50 /* ms */ * 12000 /* assume 96 MHz system clock, div8 */); STK_CTLR = 0b111000; STK_CTLR = 0b111001; @@ -858,10 +853,15 @@ __attribute__((naked)) int main(void) { STK_SR = 0; R16_USBD_CNTR = 0b11; R32_EXTEN_CTR &= ~(1 << 1); - // wtf why does this work and the other stuff doesn't? - R16_BKP_DATAR10 = 0x4170; - PFIC_CFGR = 0xbeef0080; - while (1) { asm volatile(""); } + if (ADDRESS_HI >> 8 == 0x20) { + // ram boot + ((void (*)())0x20000000)(); + } else { + // wtf why does this work and the other stuff doesn't? + R16_BKP_DATAR10 = 0x4170; + PFIC_CFGR = 0xbeef0080; + while (1) { asm volatile(""); } + } break; case STATE_SENT_DATA_IN: make_msc_csw(dCSWTag, 0); diff --git a/minimal-payload-ram/.gdbinit b/minimal-payload-ram/.gdbinit new file mode 100644 index 0000000..cefc7d4 --- /dev/null +++ b/minimal-payload-ram/.gdbinit @@ -0,0 +1,2 @@ +tar ext localhost:3333 +load diff --git a/minimal-payload-ram/Makefile b/minimal-payload-ram/Makefile new file mode 100644 index 0000000..1269bbd --- /dev/null +++ b/minimal-payload-ram/Makefile @@ -0,0 +1,33 @@ +.PHONY: all clean + +RV_ARCH = rv32imacxw + +CC = riscv-none-elf-gcc +OBJDUMP = riscv-none-elf-objdump +OBJCOPY = riscv-none-elf-objcopy +CFLAGS = -ggdb3 -Os -march=$(RV_ARCH) -ffunction-sections -fdata-sections +LDFLAGS = -ggdb3 -march=$(RV_ARCH) -Wl,--gc-sections --specs=nosys.specs + +all: main.uf2 + +main.elf: startup.o main.o + +%.uf2: %.bin + ~/code/uf2/utils/uf2conv.py -c -f 0xdeadbeef -b 0x20000000 -o $@.temp $< + xxd $@.temp | sed 's/5546 320a 5751 5d9e 0020 0000/5546 320a 5751 5d9e 0120 0000/g' | xxd -r >$@ + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ + +%.elf: linker.lds + $(CC) -Xlinker -Map=$(@:.elf=.map) -Wl,--script=linker.lds -nostartfiles -o $@ $(filter-out linker.lds,$+) + $(OBJDUMP) -xdsS $@ >$(@:.elf=.dump) + +%.o: %.S + $(CC) $(CFLAGS) -c -o $@ $< + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f *.o *.elf *.map *.dump diff --git a/minimal-payload-ram/linker.lds b/minimal-payload-ram/linker.lds new file mode 100644 index 0000000..914b1bc --- /dev/null +++ b/minimal-payload-ram/linker.lds @@ -0,0 +1,97 @@ +ENTRY( _start ) + +__stack_size = 512; +PROVIDE( _stack_size = __stack_size ); + +MEMORY +{ + /* CH32V20x_D6 -> 10 KB SRAM */ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 10K +} + +SECTIONS +{ + .vector : + { + *(.vector); + . = ALIGN(4); + } >RAM + + .text : + { + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >RAM + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >RAM + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >RAM + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >RAM + + PROVIDE(_data_lma = .); + + .data : + { + PROVIDE(_data_vma = .); + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(4); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(4); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM + + .bss : + { + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM + + PROVIDE( _end = _ebss); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + PROVIDE( _susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM +} diff --git a/minimal-payload-ram/main.bin b/minimal-payload-ram/main.bin new file mode 100755 index 0000000..e8e4fb5 Binary files /dev/null and b/minimal-payload-ram/main.bin differ diff --git a/minimal-payload-ram/main.c b/minimal-payload-ram/main.c new file mode 100644 index 0000000..31e6c07 --- /dev/null +++ b/minimal-payload-ram/main.c @@ -0,0 +1,27 @@ +#include + +#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" +__attribute__((constructor(0))) static void setup_qingke() { + asm volatile( + // Undocumented "Configure pipelining and instruction prediction" + "li t0, 0x1f\n" + "csrw 0xbc0, t0\n" + ); +} + +#define R32_RCC_APB2PCENR (*(volatile uint32_t*)0x40021018) +#define R32_GPIOA_CFGLR (*(volatile uint32_t*)0x40010800) +#define R32_GPIOA_BSHR (*(volatile uint32_t*)0x40010810) + +int main(void) { + R32_RCC_APB2PCENR |= 1 << 2; + R32_GPIOA_CFGLR = (R32_GPIOA_CFGLR & ~0xf) | (0b0010 << 0); + while (1) { + R32_GPIOA_BSHR = 1 << 0; + for (int i = 0; i < 500000; i++) + asm volatile(""); + R32_GPIOA_BSHR = 1 << 16; + for (int i = 0; i < 500000; i++) + asm volatile(""); + } +} diff --git a/minimal-payload-ram/startup.S b/minimal-payload-ram/startup.S new file mode 100644 index 0000000..8f75cc1 --- /dev/null +++ b/minimal-payload-ram/startup.S @@ -0,0 +1,67 @@ +.section .vector,"ax",@progbits +.align 1 + +.global _start +_start: + // Set up global pointer +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + // Load stack pointer + la sp, _eusrstack + + // Clear bss section + la a0, _sbss + la a1, _ebss + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + + // Call preinit array functions + la s0, __preinit_array_start + la s1, __preinit_array_end + bgeu s0, s1, 2f +1: + lw t0, (s0) + jalr t0 + addi s0, s0, 4 + bltu s0, s1, 1b +2: + + // Call init array functions + la s0, __init_array_start + la s1, __init_array_end + bgeu s0, s1, 2f +1: + lw t0, (s0) + jalr t0 + addi s0, s0, 4 + bltu s0, s1, 1b +2: + + // Invoke main with a possible mode switch + la ra, 1f + la t0, main + csrw mepc, t0 + mret + +1: + // Return from main, call fini array functions + la s0, __fini_array_start + la s1, __fini_array_end + bgeu s0, s1, 2f +1: + lw t0, (s0) + jalr t0 + addi s0, s0, 4 + bltu s0, s1, 1b +2: + + // Finally, loop infinitely + wfi + j 2b diff --git a/minimal-payload/Makefile b/minimal-payload/Makefile index 4745d4f..fa92e1a 100644 --- a/minimal-payload/Makefile +++ b/minimal-payload/Makefile @@ -13,7 +13,7 @@ all: main.uf2 main.elf: startup.o main.o %.uf2: %.bin - ~/code/uf2/utils/uf2conv.py -f 0xdeadbeef -b 0x08002000 -o $@ $< + ~/code/uf2/utils/uf2conv.py -c -f 0xdeadbeef -b 0x08002000 -o $@ $< %.bin: %.elf $(OBJCOPY) -O binary $< $@