From 78354caede7c4301b80582af36377c6cc671f063 Mon Sep 17 00:00:00 2001 From: Ivan Olenichev <> Date: Tue, 7 Dec 2021 13:37:30 +0600 Subject: [PATCH] Update firmware for RISC-V --- .../RISCV/env_Eclipse/GD32VF103x4.lds | 175 +++++++++++ .../RISCV/env_Eclipse/GD32VF103x6.lds | 175 +++++++++++ .../RISCV/env_Eclipse/GD32VF103x8.lds | 175 +++++++++++ .../RISCV/env_Eclipse/GD32VF103xB.lds | 175 +++++++++++ RISC-V/Firmware/RISCV/env_Eclipse/entry.S | 286 ++++++++++++++++++ RISC-V/Firmware/RISCV/env_Eclipse/handlers.c | 32 ++ RISC-V/Firmware/RISCV/env_Eclipse/init.c | 34 +++ RISC-V/Firmware/RISCV/env_Eclipse/start.S | 258 ++++++++++++++++ .../Firmware/RISCV/env_Eclipse/your_printf.c | 5 + RISC-V/Firmware/RISCV/stubs/_exit.c | 17 ++ RISC-V/Firmware/RISCV/stubs/close.c | 9 + RISC-V/Firmware/RISCV/stubs/fstat.c | 16 + RISC-V/Firmware/RISCV/stubs/isatty.c | 11 + RISC-V/Firmware/RISCV/stubs/lseek.c | 14 + RISC-V/Firmware/RISCV/stubs/read.c | 13 + RISC-V/Firmware/RISCV/stubs/sbrk.c | 16 + RISC-V/Firmware/RISCV/stubs/stub.h | 16 + RISC-V/Firmware/RISCV/stubs/write.c | 47 +++ RISC-V/Firmware/RISCV/stubs/write_hex.c | 18 ++ 19 files changed, 1492 insertions(+) create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x4.lds create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x6.lds create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x8.lds create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103xB.lds create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/entry.S create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/handlers.c create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/init.c create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/start.S create mode 100644 RISC-V/Firmware/RISCV/env_Eclipse/your_printf.c create mode 100644 RISC-V/Firmware/RISCV/stubs/_exit.c create mode 100644 RISC-V/Firmware/RISCV/stubs/close.c create mode 100644 RISC-V/Firmware/RISCV/stubs/fstat.c create mode 100644 RISC-V/Firmware/RISCV/stubs/isatty.c create mode 100644 RISC-V/Firmware/RISCV/stubs/lseek.c create mode 100644 RISC-V/Firmware/RISCV/stubs/read.c create mode 100644 RISC-V/Firmware/RISCV/stubs/sbrk.c create mode 100644 RISC-V/Firmware/RISCV/stubs/stub.h create mode 100644 RISC-V/Firmware/RISCV/stubs/write.c create mode 100644 RISC-V/Firmware/RISCV/stubs/write_hex.c diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x4.lds b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x4.lds new file mode 100644 index 0000000..fc3d331 --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x4.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 16k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 6k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 4k + ram (wxa!ri) : ORIGIN = 0x20001000, LENGTH = 2K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x6.lds b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x6.lds new file mode 100644 index 0000000..3cfe58a --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x6.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 32k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 10k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 7k + ram (wxa!ri) : ORIGIN = 0x20001C00, LENGTH = 3K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x8.lds b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x8.lds new file mode 100644 index 0000000..a10769d --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103x8.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 64k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 20k + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 15k + ram (wxa!ri) : ORIGIN = 0x20003C00, LENGTH = 5K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103xB.lds b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103xB.lds new file mode 100644 index 0000000..1c32e64 --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/GD32VF103xB.lds @@ -0,0 +1,175 @@ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + /* Run in FLASH */ + flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k + ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K + + /* Run in RAM */ +/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k + ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K +*/ +} + + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; + + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash + + .ilalign : + { + . = ALIGN(4); + PROVIDE( _ilm_lma = . ); + } >flash AT>flash + + .ialign : + { + PROVIDE( _ilm = . ); + } >flash AT>flash + + .text : + { + *(.rodata .rodata.*) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash + + . = ALIGN(4); + + PROVIDE (__etext = .); + PROVIDE (_etext = .);/*0x80022c8*/ + PROVIDE (etext = .);/*0x80022c8*/ + PROVIDE( _eilm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .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 = .); + } >flash AT>flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash + + . = ALIGN(4); + PROVIDE( _eilm = . ); + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash + + + .data : + { + *(.rdata) + + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/ + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram + + . = ALIGN(8); + PROVIDE( _end = . ); /*0X2000,0340*/ + PROVIDE( end = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram +} diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/entry.S b/RISC-V/Firmware/RISCV/env_Eclipse/entry.S new file mode 100644 index 0000000..a95f968 --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/entry.S @@ -0,0 +1,286 @@ +// See LICENSE for license details + +#ifndef ENTRY_S +#define ENTRY_S + +#include "riscv_encoding.h" +#include "riscv_bits.h" +#include "n200_eclic.h" +#include "n200_timer.h" + +############################################### +############################################### +# Disable Interrupt +# +.macro DISABLE_MIE + csrc CSR_MSTATUS, MSTATUS_MIE +.endm + + +############################################### +############################################### +#Save caller registers +.macro SAVE_CONTEXT + +#ifdef __riscv_flen + #if (__riscv_flen==64 ) + addi sp, sp, -20*REGBYTES - 20*FPREGBYTES + #else + addi sp, sp, -20*REGBYTES + #endif +#else + addi sp, sp, -20*REGBYTES +#endif + STORE x1, 0*REGBYTES(sp) + STORE x4, 1*REGBYTES(sp) + STORE x5, 2*REGBYTES(sp) + STORE x6, 3*REGBYTES(sp) + STORE x7, 4*REGBYTES(sp) + STORE x10, 5*REGBYTES(sp) + STORE x11, 6*REGBYTES(sp) + STORE x12, 7*REGBYTES(sp) + STORE x13, 8*REGBYTES(sp) + STORE x14, 9*REGBYTES(sp) + STORE x15, 10*REGBYTES(sp) +#ifndef __riscv_32e + STORE x16, 11*REGBYTES(sp) + STORE x17, 12*REGBYTES(sp) + STORE x28, 13*REGBYTES(sp) + STORE x29, 14*REGBYTES(sp) + STORE x30, 15*REGBYTES(sp) + STORE x31, 16*REGBYTES(sp) +#endif + +#ifdef __riscv_flen + #if (__riscv_flen == 64) + FPSTORE f0, (20*REGBYTES + 0*FPREGBYTES)(sp) + FPSTORE f1, (20*REGBYTES + 1*FPREGBYTES)(sp) + FPSTORE f2, (20*REGBYTES + 2*FPREGBYTES)(sp) + FPSTORE f3, (20*REGBYTES + 3*FPREGBYTES)(sp) + FPSTORE f4, (20*REGBYTES + 4*FPREGBYTES)(sp) + FPSTORE f5, (20*REGBYTES + 5*FPREGBYTES)(sp) + FPSTORE f6, (20*REGBYTES + 6*FPREGBYTES)(sp) + FPSTORE f7, (20*REGBYTES + 7*FPREGBYTES)(sp) + FPSTORE f10, (20*REGBYTES + 8*FPREGBYTES)(sp) + FPSTORE f11, (20*REGBYTES + 9*FPREGBYTES)(sp) + FPSTORE f12, (20*REGBYTES + 10*FPREGBYTES)(sp) + FPSTORE f13, (20*REGBYTES + 11*FPREGBYTES)(sp) + FPSTORE f14, (20*REGBYTES + 12*FPREGBYTES)(sp) + FPSTORE f15, (20*REGBYTES + 13*FPREGBYTES)(sp) + FPSTORE f16, (20*REGBYTES + 14*FPREGBYTES)(sp) + FPSTORE f17, (20*REGBYTES + 15*FPREGBYTES)(sp) + FPSTORE f28, (20*REGBYTES + 16*FPREGBYTES)(sp) + FPSTORE f29, (20*REGBYTES + 17*FPREGBYTES)(sp) + FPSTORE f30, (20*REGBYTES + 18*FPREGBYTES)(sp) + FPSTORE f31, (20*REGBYTES + 19*FPREGBYTES)(sp) + #endif +#endif + + +.endm + + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT + LOAD x1, 0*REGBYTES(sp) + LOAD x4, 1*REGBYTES(sp) + LOAD x5, 2*REGBYTES(sp) + LOAD x6, 3*REGBYTES(sp) + LOAD x7, 4*REGBYTES(sp) + LOAD x10, 5*REGBYTES(sp) + LOAD x11, 6*REGBYTES(sp) + LOAD x12, 7*REGBYTES(sp) + LOAD x13, 8*REGBYTES(sp) + LOAD x14, 9*REGBYTES(sp) + LOAD x15, 10*REGBYTES(sp) +#ifndef __riscv_32e + LOAD x16, 11*REGBYTES(sp) + LOAD x17, 12*REGBYTES(sp) + LOAD x28, 13*REGBYTES(sp) + LOAD x29, 14*REGBYTES(sp) + LOAD x30, 15*REGBYTES(sp) + LOAD x31, 16*REGBYTES(sp) +#endif + + +#ifdef __riscv_flen + #if (__riscv_flen==64) +/* Restore fp caller registers */ + FPLOAD f0, (20*REGBYTES + 0*FPREGBYTES)(sp) + FPLOAD f1, (20*REGBYTES + 1*FPREGBYTES)(sp) + FPLOAD f2, (20*REGBYTES + 2*FPREGBYTES)(sp) + FPLOAD f3, (20*REGBYTES + 3*FPREGBYTES)(sp) + FPLOAD f4, (20*REGBYTES + 4*FPREGBYTES)(sp) + FPLOAD f5, (20*REGBYTES + 5*FPREGBYTES)(sp) + FPLOAD f6, (20*REGBYTES + 6*FPREGBYTES)(sp) + FPLOAD f7, (20*REGBYTES + 7*FPREGBYTES)(sp) + FPLOAD f10, (20*REGBYTES + 8*FPREGBYTES)(sp) + FPLOAD f11, (20*REGBYTES + 9*FPREGBYTES)(sp) + FPLOAD f12, (20*REGBYTES + 10*FPREGBYTES)(sp) + FPLOAD f13, (20*REGBYTES + 11*FPREGBYTES)(sp) + FPLOAD f14, (20*REGBYTES + 12*FPREGBYTES)(sp) + FPLOAD f15, (20*REGBYTES + 13*FPREGBYTES)(sp) + FPLOAD f16, (20*REGBYTES + 14*FPREGBYTES)(sp) + FPLOAD f17, (20*REGBYTES + 15*FPREGBYTES)(sp) + FPLOAD f28, (20*REGBYTES + 16*FPREGBYTES)(sp) + FPLOAD f29, (20*REGBYTES + 17*FPREGBYTES)(sp) + FPLOAD f30, (20*REGBYTES + 18*FPREGBYTES)(sp) + FPLOAD f31, (20*REGBYTES + 19*FPREGBYTES)(sp) + #endif +#endif + + +#ifdef __riscv_flen + #if(__riscv_flen == 64 ) + addi sp, sp, 20*REGBYTES + 20*FPREGBYTES + #else + addi sp, sp, 20*REGBYTES + #endif +#else +// De-allocate the stack space + addi sp, sp, 20*REGBYTES +#endif +.endm + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT_EXCPT_X5 + LOAD x1, 0*REGBYTES(sp) + LOAD x6, 2*REGBYTES(sp) + LOAD x7, 3*REGBYTES(sp) + LOAD x10, 4*REGBYTES(sp) + LOAD x11, 5*REGBYTES(sp) + LOAD x12, 6*REGBYTES(sp) + LOAD x13, 7*REGBYTES(sp) + LOAD x14, 8*REGBYTES(sp) + LOAD x15, 9*REGBYTES(sp) +#ifndef __riscv_32e + LOAD x16, 10*REGBYTES(sp) + LOAD x17, 11*REGBYTES(sp) + LOAD x28, 12*REGBYTES(sp) + LOAD x29, 13*REGBYTES(sp) + LOAD x30, 14*REGBYTES(sp) + LOAD x31, 15*REGBYTES(sp) +#endif +.endm + +############################################### +############################################### +#restore caller registers +.macro RESTORE_CONTEXT_ONLY_X5 + LOAD x5, 1*REGBYTES(sp) +.endm + +############################################### +############################################### +# Save the mepc and mstatus +# +.macro SAVE_EPC_STATUS + csrr x5, CSR_MEPC + STORE x5, 16*REGBYTES(sp) + csrr x5, CSR_MSTATUS + STORE x5, 17*REGBYTES(sp) + csrr x5, CSR_MSUBM + STORE x5, 18*REGBYTES(sp) +.endm + +############################################### +############################################### +# Restore the mepc and mstatus +# +.macro RESTORE_EPC_STATUS + LOAD x5, 16*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 17*REGBYTES(sp) + csrw CSR_MSTATUS, x5 + LOAD x5, 18*REGBYTES(sp) + csrw CSR_MSUBM, x5 +.endm + + + +############################################### +############################################### +// Trap entry point +// + .section .text.trap + .align 6// In CLIC mode, the trap entry must be 64bytes aligned + .global trap_entry +.weak trap_entry +trap_entry: + // Allocate the stack space + // addi sp, sp, -19*REGBYTES + + // Save the caller saving registers (context) + SAVE_CONTEXT + // Save the MEPC/Mstatus/Msubm reg + SAVE_EPC_STATUS + + // Set the function argument + csrr a0, mcause + mv a1, sp + // Call the function + call handle_trap + + // Restore the MEPC/Mstatus/Msubm reg + RESTORE_EPC_STATUS + // Restore the caller saving registers (context) + RESTORE_CONTEXT + + // De-allocate the stack space + // addi sp, sp, 19*REGBYTES + // Return to regular code + mret + + +############################################### +############################################### +// IRQ entry point +// + .section .text.irq + .align 2 + .global irq_entry +.weak irq_entry +irq_entry: // -------------> This label will be set to MTVT2 register + // Allocate the stack space + + + SAVE_CONTEXT// Save 16 regs + + //------This special CSR read operation, which is actually use mcause as operand to directly store it to memory + csrrwi x0, CSR_PUSHMCAUSE, 17 + //------This special CSR read operation, which is actually use mepc as operand to directly store it to memory + csrrwi x0, CSR_PUSHMEPC, 18 + //------This special CSR read operation, which is actually use Msubm as operand to directly store it to memory + csrrwi x0, CSR_PUSHMSUBM, 19 + +service_loop: + //------This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest + // ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and + // update the link register + csrrw ra, CSR_JALMNXTI, ra + + //RESTORE_CONTEXT_EXCPT_X5 + + #---- Critical section with interrupts disabled ----------------------- + DISABLE_MIE # Disable interrupts + + LOAD x5, 19*REGBYTES(sp) + csrw CSR_MSUBM, x5 + LOAD x5, 18*REGBYTES(sp) + csrw CSR_MEPC, x5 + LOAD x5, 17*REGBYTES(sp) + csrw CSR_MCAUSE, x5 + + + RESTORE_CONTEXT + + + // Return to regular code + mret + + +#endif \ No newline at end of file diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/handlers.c b/RISC-V/Firmware/RISCV/env_Eclipse/handlers.c new file mode 100644 index 0000000..8155afe --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/handlers.c @@ -0,0 +1,32 @@ +//See LICENSE for license details. +#include +#include +#include +#include "riscv_encoding.h" +#include "n200_func.h" + +__attribute__((weak)) uintptr_t handle_nmi() +{ + write(1, "nmi\n", 5); + _exit(1); + return 0; +} + + +__attribute__((weak)) uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp) +{ + if((mcause & 0xFFF) == 0xFFF) { + handle_nmi(); + } + write(1, "trap\n", 5); + //printf("In trap handler, the mcause is %d\n", mcause); + //printf("In trap handler, the mepc is 0x%x\n", read_csr(mepc)); + //printf("In trap handler, the mtval is 0x%x\n", read_csr(mbadaddr)); + _exit(mcause); + return 0; +} + + + + + diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/init.c b/RISC-V/Firmware/RISCV/env_Eclipse/init.c new file mode 100644 index 0000000..39a72ab --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/init.c @@ -0,0 +1,34 @@ +//See LICENSE for license details. +#include +#include +#include +#include +#include "riscv_encoding.h" +#include "n200_func.h" + +extern uint32_t disable_mcycle_minstret(); +void _init() +{ + SystemInit(); + + //ECLIC init + eclic_init(ECLIC_NUM_INTERRUPTS); + eclic_mode_enable(); + + //printf("After ECLIC mode enabled, the mtvec value is %x \n\n\r", read_csr(mtvec)); + + // // It must be NOTED: + // // * In the RISC-V arch, if user mode and PMP supported, then by default if PMP is not configured + // // with valid entries, then user mode cannot access any memory, and cannot execute any instructions. + // // * So if switch to user-mode and still want to continue, then you must configure PMP first + //pmp_open_all_space(); + //switch_m2u_mode(); + + /* Before enter into main, add the cycle/instret disable by default to save power, + only use them when needed to measure the cycle/instret */ + disable_mcycle_minstret(); +} + +void _fini() +{ +} diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/start.S b/RISC-V/Firmware/RISCV/env_Eclipse/start.S new file mode 100644 index 0000000..d16f0d3 --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/start.S @@ -0,0 +1,258 @@ +// See LICENSE for license details. + +#include "riscv_encoding.h" + + .section .init + + .weak eclic_msip_handler + .weak eclic_mtip_handler + .weak eclic_bwei_handler + .weak eclic_pmovi_handler + .weak WWDGT_IRQHandler + .weak LVD_IRQHandler + .weak TAMPER_IRQHandler + .weak RTC_IRQHandler + .weak FMC_IRQHandler + .weak RCU_IRQHandler + .weak EXTI0_IRQHandler + .weak EXTI1_IRQHandler + .weak EXTI2_IRQHandler + .weak EXTI3_IRQHandler + .weak EXTI4_IRQHandler + .weak DMA0_Channel0_IRQHandler + .weak DMA0_Channel1_IRQHandler + .weak DMA0_Channel2_IRQHandler + .weak DMA0_Channel3_IRQHandler + .weak DMA0_Channel4_IRQHandler + .weak DMA0_Channel5_IRQHandler + .weak DMA0_Channel6_IRQHandler + .weak ADC0_1_IRQHandler + .weak CAN0_TX_IRQHandler + .weak CAN0_RX0_IRQHandler + .weak CAN0_RX1_IRQHandler + .weak CAN0_EWMC_IRQHandler + .weak EXTI5_9_IRQHandler + .weak TIMER0_BRK_IRQHandler + .weak TIMER0_UP_IRQHandler + .weak TIMER0_TRG_CMT_IRQHandler + .weak TIMER0_Channel_IRQHandler + .weak TIMER1_IRQHandler + .weak TIMER2_IRQHandler + .weak TIMER3_IRQHandler + .weak I2C0_EV_IRQHandler + .weak I2C0_ER_IRQHandler + .weak I2C1_EV_IRQHandler + .weak I2C1_ER_IRQHandler + .weak SPI0_IRQHandler + .weak SPI1_IRQHandler + .weak USART0_IRQHandler + .weak USART1_IRQHandler + .weak USART2_IRQHandler + .weak EXTI10_15_IRQHandler + .weak RTC_Alarm_IRQHandler + .weak USBFS_WKUP_IRQHandler + .weak EXMC_IRQHandler + .weak TIMER4_IRQHandler + .weak SPI2_IRQHandler + .weak UART3_IRQHandler + .weak UART4_IRQHandler + .weak TIMER5_IRQHandler + .weak TIMER6_IRQHandler + .weak DMA1_Channel0_IRQHandler + .weak DMA1_Channel1_IRQHandler + .weak DMA1_Channel2_IRQHandler + .weak DMA1_Channel3_IRQHandler + .weak DMA1_Channel4_IRQHandler + .weak CAN1_TX_IRQHandler + .weak CAN1_RX0_IRQHandler + .weak CAN1_RX1_IRQHandler + .weak CAN1_EWMC_IRQHandler + .weak USBFS_IRQHandler + +vector_base: + j _start + .align 2 + .word 0 + .word 0 + .word eclic_msip_handler + .word 0 + .word 0 + .word 0 + .word eclic_mtip_handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word eclic_bwei_handler + .word eclic_pmovi_handler + .word WWDGT_IRQHandler + .word LVD_IRQHandler + .word TAMPER_IRQHandler + .word RTC_IRQHandler + .word FMC_IRQHandler + .word RCU_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA0_Channel0_IRQHandler + .word DMA0_Channel1_IRQHandler + .word DMA0_Channel2_IRQHandler + .word DMA0_Channel3_IRQHandler + .word DMA0_Channel4_IRQHandler + .word DMA0_Channel5_IRQHandler + .word DMA0_Channel6_IRQHandler + .word ADC0_1_IRQHandler + .word CAN0_TX_IRQHandler + .word CAN0_RX0_IRQHandler + .word CAN0_RX1_IRQHandler + .word CAN0_EWMC_IRQHandler + .word EXTI5_9_IRQHandler + .word TIMER0_BRK_IRQHandler + .word TIMER0_UP_IRQHandler + .word TIMER0_TRG_CMT_IRQHandler + .word TIMER0_Channel_IRQHandler + .word TIMER1_IRQHandler + .word TIMER2_IRQHandler + .word TIMER3_IRQHandler + .word I2C0_EV_IRQHandler + .word I2C0_ER_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word SPI0_IRQHandler + .word SPI1_IRQHandler + .word USART0_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word EXTI10_15_IRQHandler + .word RTC_Alarm_IRQHandler + .word USBFS_WKUP_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word EXMC_IRQHandler + .word 0 + .word TIMER4_IRQHandler + .word SPI2_IRQHandler + .word UART3_IRQHandler + .word UART4_IRQHandler + .word TIMER5_IRQHandler + .word TIMER6_IRQHandler + .word DMA1_Channel0_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word 0 + .word 0 + .word CAN1_TX_IRQHandler + .word CAN1_RX0_IRQHandler + .word CAN1_RX1_IRQHandler + .word CAN1_EWMC_IRQHandler + .word USBFS_IRQHandler + + .globl _start + .type _start,@function + +_start: + + csrc CSR_MSTATUS, MSTATUS_MIE + /* Jump to logical address first to ensure correct operation of RAM region */ + la a0, _start + li a1, 1 + slli a1, a1, 29 + bleu a1, a0, _start0800 + srli a1, a1, 2 + bleu a1, a0, _start0800 + la a0, _start0800 + add a0, a0, a1 + jr a0 + +_start0800: + + /* Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL */ + li t0, 0x200 + csrs CSR_MMISC_CTL, t0 + + /* Intial the mtvt*/ + la t0, vector_base + csrw CSR_MTVT, t0 + + /* Intial the mtvt2 and enable it*/ + la t0, irq_entry + csrw CSR_MTVT2, t0 + csrs CSR_MTVT2, 0x1 + + /* Intial the CSR MTVEC for the Trap ane NMI base addr*/ + la t0, trap_entry + csrw CSR_MTVEC, t0 + +#ifdef __riscv_flen + /* Enable FPU */ + li t0, MSTATUS_FS + csrs mstatus, t0 + csrw fcsr, x0 +#endif + +.option push +.option norelax + la gp, __global_pointer$ +.option pop + la sp, _sp + + /* Load data section */ + la a0, _data_lma + la a1, _data + la a2, _edata + bgeu a1, a2, 2f +1: + lw t0, (a0) + sw t0, (a1) + addi a0, a0, 4 + addi a1, a1, 4 + bltu a1, a2, 1b +2: + /* Clear bss section */ + la a0, __bss_start + la a1, _end + bgeu a0, a1, 2f +1: + sw zero, (a0) + addi a0, a0, 4 + bltu a0, a1, 1b +2: + /*enable mcycle_minstret*/ + csrci CSR_MCOUNTINHIBIT, 0x5 + /* Call global constructors */ +// la a0, __libc_fini_array +// call atexit +// call __libc_init_array + call _init + + /* argc = argv = 0 */ + li a0, 0 + li a1, 0 + call main +// tail exit + +1: + j 1b + + .global disable_mcycle_minstret +disable_mcycle_minstret: + csrsi CSR_MCOUNTINHIBIT, 0x5 + ret + + .global enable_mcycle_minstret +enable_mcycle_minstret: + csrci CSR_MCOUNTINHIBIT, 0x5 + ret + diff --git a/RISC-V/Firmware/RISCV/env_Eclipse/your_printf.c b/RISC-V/Firmware/RISCV/env_Eclipse/your_printf.c new file mode 100644 index 0000000..bbb95b6 --- /dev/null +++ b/RISC-V/Firmware/RISCV/env_Eclipse/your_printf.c @@ -0,0 +1,5 @@ +int __wrap_printf(const char* fmt, ...) +{ + // You can implement your own printf to reduce the code size, because the printf is really a big function +} + diff --git a/RISC-V/Firmware/RISCV/stubs/_exit.c b/RISC-V/Firmware/RISCV/stubs/_exit.c new file mode 100644 index 0000000..33467d0 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/_exit.c @@ -0,0 +1,17 @@ +/* See LICENSE of license details. */ + +#include + +#include "stub.h" + + +void _exit(int code) +{ + const char message[] = "\nProgram has exited with code:"; + + write(STDERR_FILENO, message, sizeof(message) - 1); + write_hex(STDERR_FILENO, code); + write(STDERR_FILENO, "\n", 1); + + for (;;); +} diff --git a/RISC-V/Firmware/RISCV/stubs/close.c b/RISC-V/Firmware/RISCV/stubs/close.c new file mode 100644 index 0000000..e50362e --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/close.c @@ -0,0 +1,9 @@ +/* See LICENSE of license details. */ + +#include +#include "stub.h" + +int _close(int fd) +{ + return _stub(EBADF); +} diff --git a/RISC-V/Firmware/RISCV/stubs/fstat.c b/RISC-V/Firmware/RISCV/stubs/fstat.c new file mode 100644 index 0000000..c30d27c --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/fstat.c @@ -0,0 +1,16 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" + +int _fstat(int fd, struct stat* st) +{ + if (isatty(fd)) { + st->st_mode = S_IFCHR; + return 0; + } + + return _stub(EBADF); +} diff --git a/RISC-V/Firmware/RISCV/stubs/isatty.c b/RISC-V/Firmware/RISCV/stubs/isatty.c new file mode 100644 index 0000000..a590eba --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/isatty.c @@ -0,0 +1,11 @@ +/* See LICENSE of license details. */ + +#include + +int _isatty(int fd) +{ + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) + return 1; + + return 0; +} diff --git a/RISC-V/Firmware/RISCV/stubs/lseek.c b/RISC-V/Firmware/RISCV/stubs/lseek.c new file mode 100644 index 0000000..f519b51 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/lseek.c @@ -0,0 +1,14 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include "stub.h" + +off_t _lseek(int fd, off_t ptr, int dir) +{ + if (isatty(fd)) + return 0; + + return _stub(EBADF); +} diff --git a/RISC-V/Firmware/RISCV/stubs/read.c b/RISC-V/Firmware/RISCV/stubs/read.c new file mode 100644 index 0000000..c874f67 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/read.c @@ -0,0 +1,13 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include + +#include "stub.h" + +ssize_t _read(int fd, void* ptr, size_t len) +{ + return _stub(EBADF); +} diff --git a/RISC-V/Firmware/RISCV/stubs/sbrk.c b/RISC-V/Firmware/RISCV/stubs/sbrk.c new file mode 100644 index 0000000..7d28568 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/sbrk.c @@ -0,0 +1,16 @@ +/* See LICENSE of license details. */ + +#include + +void *_sbrk(ptrdiff_t incr) +{ + extern char _end[]; + extern char _heap_end[]; + static char *curbrk = _end; + + if ((curbrk + incr < _end) || (curbrk + incr > _heap_end)) + return NULL - 1; + + curbrk += incr; + return curbrk - incr; +} \ No newline at end of file diff --git a/RISC-V/Firmware/RISCV/stubs/stub.h b/RISC-V/Firmware/RISCV/stubs/stub.h new file mode 100644 index 0000000..88039e5 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/stub.h @@ -0,0 +1,16 @@ +/* See LICENSE of license details. */ +#ifndef _NUCLEI_SYS_STUB_H +#define _NUCLEI_SYS_STUB_H + +#include +#include + +void write_hex(int fd, unsigned long int hex); + +static inline int _stub(int err) +{ + return -1; +} + + +#endif /* _NUCLEI_SYS_STUB_H */ diff --git a/RISC-V/Firmware/RISCV/stubs/write.c b/RISC-V/Firmware/RISCV/stubs/write.c new file mode 100644 index 0000000..8836b70 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/write.c @@ -0,0 +1,47 @@ +/* See LICENSE of license details. */ + +#include +#include +#include +#include +#include +#include + +#include "stub.h" +#include "gd32vf103.h" + +typedef unsigned int size_t; + +extern int _put_char(int ch) __attribute__((weak)); + +ssize_t _write(int fd, const void* ptr, size_t len) { + const uint8_t * current = (const uint8_t *) ptr; + +// if (isatty(fd)) + { + for (size_t jj = 0; jj < len; jj++) { + _put_char(current[jj]); + + if (current[jj] == '\n') { + _put_char('\r'); + } + } + return len; + } + + return _stub(EBADF); +} + +int puts(const char* string) { + return _write(0, (const void *) string, strlen(string)); +} + +int _put_char(int ch) +{ + usart_data_transmit(USART0, (uint8_t) ch ); + while (usart_flag_get(USART0, USART_FLAG_TBE)== RESET){ + } + + return ch; +} + diff --git a/RISC-V/Firmware/RISCV/stubs/write_hex.c b/RISC-V/Firmware/RISCV/stubs/write_hex.c new file mode 100644 index 0000000..f7aa9a4 --- /dev/null +++ b/RISC-V/Firmware/RISCV/stubs/write_hex.c @@ -0,0 +1,18 @@ +/* See LICENSE of license details. */ + +#include +#include + +void write_hex(int fd, unsigned long int hex) +{ + uint8_t ii; + uint8_t jj; + char towrite; + write(fd , "0x", 2); + for (ii = sizeof(unsigned long int) * 2 ; ii > 0; ii--) { + jj = ii - 1; + uint8_t digit = ((hex & (0xF << (jj*4))) >> (jj*4)); + towrite = digit < 0xA ? ('0' + digit) : ('A' + (digit - 0xA)); + write(fd, &towrite, 1); + } +}