diff --git a/hello-world/bsp/drivers/clic/clic_driver.c b/bare-metal-bsp/drivers/clic/clic_driver.c similarity index 100% rename from hello-world/bsp/drivers/clic/clic_driver.c rename to bare-metal-bsp/drivers/clic/clic_driver.c diff --git a/hello-world/bsp/drivers/clic/clic_driver.h b/bare-metal-bsp/drivers/clic/clic_driver.h similarity index 100% rename from hello-world/bsp/drivers/clic/clic_driver.h rename to bare-metal-bsp/drivers/clic/clic_driver.h diff --git a/dhrystone/bsp/drivers/fe300prci/fe300prci_driver.c b/bare-metal-bsp/drivers/fe300prci/fe300prci_driver.c similarity index 100% rename from dhrystone/bsp/drivers/fe300prci/fe300prci_driver.c rename to bare-metal-bsp/drivers/fe300prci/fe300prci_driver.c diff --git a/demo_gpio/bsp/drivers/fe300prci/fe300prci_driver.h b/bare-metal-bsp/drivers/fe300prci/fe300prci_driver.h similarity index 100% rename from demo_gpio/bsp/drivers/fe300prci/fe300prci_driver.h rename to bare-metal-bsp/drivers/fe300prci/fe300prci_driver.h diff --git a/demo_gpio/bsp/drivers/plic/plic_driver.c b/bare-metal-bsp/drivers/plic/plic_driver.c similarity index 100% rename from demo_gpio/bsp/drivers/plic/plic_driver.c rename to bare-metal-bsp/drivers/plic/plic_driver.c diff --git a/demo_gpio/bsp/drivers/plic/plic_driver.h b/bare-metal-bsp/drivers/plic/plic_driver.h similarity index 100% rename from demo_gpio/bsp/drivers/plic/plic_driver.h rename to bare-metal-bsp/drivers/plic/plic_driver.h diff --git a/bare-metal-bsp/env/.gitignore b/bare-metal-bsp/env/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/env/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/riscv-bldc-forced-commutation/bsp/env/common.mk b/bare-metal-bsp/env/common-clang.mk similarity index 74% rename from riscv-bldc-forced-commutation/bsp/env/common.mk rename to bare-metal-bsp/env/common-clang.mk index 0ca2c70..486dee8 100644 --- a/riscv-bldc-forced-commutation/bsp/env/common.mk +++ b/bare-metal-bsp/env/common-clang.mk @@ -22,7 +22,7 @@ INCLUDES += -I$(BSP_BASE)/drivers/ INCLUDES += -I$(ENV_DIR) INCLUDES += -I$(PLATFORM_DIR) -TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin +TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/ LDFLAGS += -T $(LINKER_SCRIPT) -nostartfiles LDFLAGS += -L$(ENV_DIR) --specs=nano.specs @@ -40,15 +40,17 @@ CFLAGS += -march=$(RISCV_ARCH) CFLAGS += -mabi=$(RISCV_ABI) CFLAGS += -mcmodel=medany -TRIPLET?=riscv64-unknown-elf -CXX=$(TOOL_DIR)/$(TRIPLET)-c++ -CC=$(TOOL_DIR)/$(TRIPLET)-gcc -LD=$(TOOL_DIR)/$(TRIPLET)-gcc -AR=$(TOOL_DIR)/$(TRIPLET)-ar +TRIPLET?=riscv32 +CXX=$(LLVM_TOOL_DIR)clang++ --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include +CC=$(LLVM_TOOL_DIR)clang --target=$(TRIPLET) -isystem $(TOOL_DIR)/../$(TRIPLET)/include +LD=$(TOOL_DIR)$(TRIPLET)-gcc +AR=$(TOOL_DIR)$(TRIPLET)-ar +OBJDUMP := $(TOOL_DIR)/$(TRIPLET)-objdump $(TARGET): $(LINK_OBJS) $(LINK_DEPS) $(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@ + $(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis $(ASM_OBJS): %.o: %.S $(HEADERS) $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< @@ -61,6 +63,10 @@ $(CXX_OBJS): %.o: %.cpp $(HEADERS) .PHONY: clean clean: + rm -f $(TARGET) $(LINK_OBJS) + +.PHONY: clean-all +clean-all: rm -f $(CLEAN_OBJS) $(LIBWRAP) -endif # _SIFIVE_MK_COMMON +endif diff --git a/bare-metal-bsp/env/common-gcc.mk b/bare-metal-bsp/env/common-gcc.mk new file mode 100644 index 0000000..061521c --- /dev/null +++ b/bare-metal-bsp/env/common-gcc.mk @@ -0,0 +1,74 @@ +ifndef _MK_COMMON +_MK_COMMON := # defined + +.PHONY: all +all: $(TARGET) + +include $(BSP_BASE)/libwrap/libwrap.mk + +BOARD?=iss +ENV_DIR = $(BSP_BASE)/env +PLATFORM_DIR = $(ENV_DIR)/$(BOARD) + +ASM_SRCS += $(ENV_DIR)/start.S +ASM_SRCS += $(ENV_DIR)/entry.S +C_SRCS += $(PLATFORM_DIR)/init.c + +LINKER_SCRIPT := $(PLATFORM_DIR)/$(LINK_TARGET).lds + +INCLUDES += -I$(BSP_BASE)/include +INCLUDES += -I$(BSP_BASE)/drivers/ +INCLUDES += -I$(ENV_DIR) +INCLUDES += -I$(PLATFORM_DIR) + +TOOL_DIR ?= $(BSP_BASE)/../toolchain/bin/ + +LDFLAGS += -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) +LDFLAGS += -T $(LINKER_SCRIPT) -Wl,-Map=$(TARGET).map -nostartfiles +LDFLAGS += -L$(ENV_DIR) +# --specs=nano.specs + +ASM_OBJS := $(ASM_SRCS:.S=.o) +C_OBJS := $(C_SRCS:.c=.o) +CXX_OBJS := $(CXX_SRCS:.cpp=.o) + +LINK_OBJS += $(ASM_OBJS) $(C_OBJS) $(CXX_OBJS) +LINK_DEPS += $(LINKER_SCRIPT) + +CLEAN_OBJS += $(TARGET) $(LINK_OBJS) + +GCCVERSION = $(shell $(CC) --version | grep gcc | awk '{print($NF);}') +ifeq ($(GCCVERSION),9.2) + CFLAGS += -march=$(RISCV_ARCH) +else + CFLAGS += -march=$(RISCV_ARCH)_zicsr_zifencei +endif +CFLAGS += -mabi=$(RISCV_ABI) +CFLAGS += -mcmodel=medany + +TRIPLET?=riscv64-unknown-elf +CXX=$(TOOL_DIR)$(TRIPLET)-c++ +CC=$(TOOL_DIR)$(TRIPLET)-gcc +LD=$(TOOL_DIR)$(TRIPLET)-gcc +AR=$(TOOL_DIR)$(TRIPLET)-ar +OBJDUMP := $(TOOL_DIR)$(TRIPLET)-objdump + + +$(TARGET): $(LINK_OBJS) $(LINK_DEPS) + $(LD) $(LINK_OBJS) $(LDFLAGS) $(LIBWRAP) -o $@ + $(OBJDUMP) -d -S $(TARGET) > $(TARGET).dis + +$(ASM_OBJS): %.o: %.S $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(C_OBJS): %.o: %.c $(HEADERS) + $(CC) $(CFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +$(CXX_OBJS): %.o: %.cpp $(HEADERS) + $(CXX) $(CFLAGS) $(CXXFLAGS) $(INCLUDES) -include sys/cdefs.h -c -o $@ $< + +.PHONY: clean +clean: + rm -f $(CLEAN_OBJS) $(LIBWRAP) + +endif diff --git a/demo_gpio/bsp/env/encoding.h b/bare-metal-bsp/env/encoding.h similarity index 100% rename from demo_gpio/bsp/env/encoding.h rename to bare-metal-bsp/env/encoding.h diff --git a/riscv-bldc-forced-commutation/bsp/env/entry.S b/bare-metal-bsp/env/entry.S similarity index 96% rename from riscv-bldc-forced-commutation/bsp/env/entry.S rename to bare-metal-bsp/env/entry.S index 261b2a4..9d61210 100644 --- a/riscv-bldc-forced-commutation/bsp/env/entry.S +++ b/bare-metal-bsp/env/entry.S @@ -4,11 +4,10 @@ #define ENTRY_S #include "encoding.h" -#include "sifive/bits.h" +#include "rtl/bits.h" .section .text.entry .align 2 - .weak trap_entry .global trap_entry trap_entry: addi sp, sp, -32*REGBYTES @@ -28,6 +27,7 @@ trap_entry: STORE x13, 13*REGBYTES(sp) STORE x14, 14*REGBYTES(sp) STORE x15, 15*REGBYTES(sp) +#ifndef __riscv_abi_rve STORE x16, 16*REGBYTES(sp) STORE x17, 17*REGBYTES(sp) STORE x18, 18*REGBYTES(sp) @@ -44,7 +44,7 @@ trap_entry: STORE x29, 29*REGBYTES(sp) STORE x30, 30*REGBYTES(sp) STORE x31, 31*REGBYTES(sp) - +#endif csrr a0, mcause csrr a1, mepc mv a2, sp @@ -70,6 +70,7 @@ trap_entry: LOAD x13, 13*REGBYTES(sp) LOAD x14, 14*REGBYTES(sp) LOAD x15, 15*REGBYTES(sp) +#ifndef __riscv_abi_rve LOAD x16, 16*REGBYTES(sp) LOAD x17, 17*REGBYTES(sp) LOAD x18, 18*REGBYTES(sp) @@ -86,7 +87,7 @@ trap_entry: LOAD x29, 29*REGBYTES(sp) LOAD x30, 30*REGBYTES(sp) LOAD x31, 31*REGBYTES(sp) - +#endif addi sp, sp, 32*REGBYTES mret diff --git a/bare-metal-bsp/env/iss/.gitignore b/bare-metal-bsp/env/iss/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/env/iss/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/riscv-bldc-forced-commutation/bsp/env/freedom-e300-arty/init.c b/bare-metal-bsp/env/iss/init.c similarity index 56% rename from riscv-bldc-forced-commutation/bsp/env/freedom-e300-arty/init.c rename to bare-metal-bsp/env/iss/init.c index a6f4b39..1269c8c 100644 --- a/riscv-bldc-forced-commutation/bsp/env/freedom-e300-arty/init.c +++ b/bare-metal-bsp/env/iss/init.c @@ -1,4 +1,3 @@ -//See LICENSE for license details. #include #include #include @@ -9,38 +8,55 @@ extern int main(int argc, char** argv); extern void trap_entry(); -static unsigned long get_cpu_freq() +static unsigned long mtime_lo(void) { - return 65000000; + unsigned long ret; + __asm volatile("rdtime %0":"=r"(ret)); + return ret; } -unsigned long get_timer_freq() + +#if __riscv_xlen==32 + +static uint32_t mtime_hi(void) { - return get_cpu_freq(); + unsigned long ret; + __asm volatile("rdtimeh %0":"=r"(ret)); + return ret; } uint64_t get_timer_value() { -#if __riscv_xlen == 32 while (1) { - uint32_t hi = read_csr(mcycleh); - uint32_t lo = read_csr(mcycle); - if (hi == read_csr(mcycleh)) + uint32_t hi = mtime_hi(); + uint32_t lo = mtime_lo(); + if (hi == mtime_hi()) return ((uint64_t)hi << 32) | lo; } -#else - return read_csr(mcycle); -#endif } -static void uart_init(size_t baud_rate) +#elif __riscv_xlen==64 + +uint64_t get_timer_value() { - GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; - GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK; - UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1; - UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; + return mtime_lo(); } +#endif + +unsigned long get_timer_freq() +{ + return 32768; +} + +unsigned long get_cpu_freq() +{ + return 10000000; +} + +void init_pll(void){ + +} #ifdef USE_PLIC extern void handle_m_ext_interrupt(); @@ -65,7 +81,7 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) #endif } else { - write(1, "Unhandled Trap:\n", 16); + write(1, "trap\n", 5); _exit(1 + mcause); } return epc; @@ -73,13 +89,17 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) void _init() { - #ifndef NO_INIT - uart_init(115200); - + +#ifndef NO_INIT + init_pll(); printf("core freq at %d Hz\n", get_cpu_freq()); - write_csr(mtvec, &trap_entry); - #endif + if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present + write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping + write_csr(fcsr, 0); // initialize rounding mode, undefined at reset + } +#endif + } void _fini() diff --git a/hello/bsp/env/freedom-e300-arty/link.lds b/bare-metal-bsp/env/iss/link.lds similarity index 90% rename from hello/bsp/env/freedom-e300-arty/link.lds rename to bare-metal-bsp/env/iss/link.lds index 90e5c8f..575c22e 100644 --- a/hello/bsp/env/freedom-e300-arty/link.lds +++ b/bare-metal-bsp/env/iss/link.lds @@ -4,8 +4,8 @@ ENTRY( _start ) MEMORY { - flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K + flash (rxai!w) : ORIGIN = 0x00000020, LENGTH = 1M + ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 16K } PHDRS @@ -19,7 +19,7 @@ SECTIONS { __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; - .init : + .init ORIGIN(flash) : { KEEP (*(SORT_NONE(.init))) } >flash AT>flash :flash @@ -118,6 +118,7 @@ SECTIONS .data : { + __DATA_BEGIN__ = .; *(.data .data.*) *(.gnu.linkonce.d.*) } >ram AT>flash :ram_init @@ -134,6 +135,7 @@ SECTIONS .sdata : { + __SDATA_BEGIN__ = .; *(.sdata .sdata.*) *(.gnu.linkonce.s.*) } >ram AT>flash :ram_init @@ -155,6 +157,8 @@ SECTIONS } >ram AT>ram :ram . = ALIGN(8); + __BSS_END__ = .; + __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); PROVIDE( _end = . ); PROVIDE( end = . ); @@ -164,4 +168,7 @@ SECTIONS . = __stack_size; PROVIDE( _sp = . ); } >ram AT>ram :ram + + PROVIDE( tohost = 0xfffffff0 ); + PROVIDE( fromhost = 0xfffffff8 ); } diff --git a/bare-metal-bsp/env/iss/platform.h b/bare-metal-bsp/env/iss/platform.h new file mode 100644 index 0000000..59e6fd5 --- /dev/null +++ b/bare-metal-bsp/env/iss/platform.h @@ -0,0 +1,30 @@ +// See LICENSE for license details. + +#ifndef _ISS_PLATFORM_H +#define _ISS_PLATFORM_H + +// Some things missing from the official encoding.h +#define MCAUSE_INT 0x80000000 +#define MCAUSE_CAUSE 0x7FFFFFFF + +#include "rtl/const.h" +/**************************************************************************** + * Platform definitions + *****************************************************************************/ + +#define MEM_BASE_ADDR _AC(0x00000000,UL) + +// Helper functions +#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) +#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) + +// Misc + +#include + +void init_pll(void); +unsigned long get_cpu_freq(void); +unsigned long get_timer_freq(void); +uint64_t get_timer_value(void); + +#endif /* _ISS_PLATFORM_H */ diff --git a/bare-metal-bsp/env/rtl/.gitignore b/bare-metal-bsp/env/rtl/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/env/rtl/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/hello/bsp/env/freedom-e300-arty/init.c b/bare-metal-bsp/env/rtl/init.c similarity index 56% rename from hello/bsp/env/freedom-e300-arty/init.c rename to bare-metal-bsp/env/rtl/init.c index a6f4b39..1269c8c 100644 --- a/hello/bsp/env/freedom-e300-arty/init.c +++ b/bare-metal-bsp/env/rtl/init.c @@ -1,4 +1,3 @@ -//See LICENSE for license details. #include #include #include @@ -9,38 +8,55 @@ extern int main(int argc, char** argv); extern void trap_entry(); -static unsigned long get_cpu_freq() +static unsigned long mtime_lo(void) { - return 65000000; + unsigned long ret; + __asm volatile("rdtime %0":"=r"(ret)); + return ret; } -unsigned long get_timer_freq() + +#if __riscv_xlen==32 + +static uint32_t mtime_hi(void) { - return get_cpu_freq(); + unsigned long ret; + __asm volatile("rdtimeh %0":"=r"(ret)); + return ret; } uint64_t get_timer_value() { -#if __riscv_xlen == 32 while (1) { - uint32_t hi = read_csr(mcycleh); - uint32_t lo = read_csr(mcycle); - if (hi == read_csr(mcycleh)) + uint32_t hi = mtime_hi(); + uint32_t lo = mtime_lo(); + if (hi == mtime_hi()) return ((uint64_t)hi << 32) | lo; } -#else - return read_csr(mcycle); -#endif } -static void uart_init(size_t baud_rate) +#elif __riscv_xlen==64 + +uint64_t get_timer_value() { - GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; - GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK; - UART0_REG(UART_REG_DIV) = get_cpu_freq() / baud_rate - 1; - UART0_REG(UART_REG_TXCTRL) |= UART_TXEN; + return mtime_lo(); } +#endif + +unsigned long get_timer_freq() +{ + return 32768; +} + +unsigned long get_cpu_freq() +{ + return 10000000; +} + +void init_pll(void){ + +} #ifdef USE_PLIC extern void handle_m_ext_interrupt(); @@ -65,7 +81,7 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) #endif } else { - write(1, "Unhandled Trap:\n", 16); + write(1, "trap\n", 5); _exit(1 + mcause); } return epc; @@ -73,13 +89,17 @@ uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc) void _init() { - #ifndef NO_INIT - uart_init(115200); - + +#ifndef NO_INIT + init_pll(); printf("core freq at %d Hz\n", get_cpu_freq()); - write_csr(mtvec, &trap_entry); - #endif + if (read_csr(misa) & (1 << ('F' - 'A'))) { // if F extension is present + write_csr(mstatus, MSTATUS_FS); // allow FPU instructions without trapping + write_csr(fcsr, 0); // initialize rounding mode, undefined at reset + } +#endif + } void _fini() diff --git a/hello/bsp/env/iss/link.lds b/bare-metal-bsp/env/rtl/link.lds similarity index 94% rename from hello/bsp/env/iss/link.lds rename to bare-metal-bsp/env/rtl/link.lds index bc60026..48719fe 100644 --- a/hello/bsp/env/iss/link.lds +++ b/bare-metal-bsp/env/rtl/link.lds @@ -4,9 +4,8 @@ ENTRY( _start ) MEMORY { - /*flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M*/ - flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K + flash (rxai!w) : ORIGIN = 0x00000000, LENGTH = 1M + ram (wxa!ri) : ORIGIN = 0x10000000, LENGTH = 16K } PHDRS @@ -20,7 +19,7 @@ SECTIONS { __stack_size = DEFINED(__stack_size) ? __stack_size : 2K; - .init : + .init ORIGIN(flash) : { KEEP (*(SORT_NONE(.init))) } >flash AT>flash :flash @@ -165,4 +164,7 @@ SECTIONS . = __stack_size; PROVIDE( _sp = . ); } >ram AT>ram :ram + + PROVIDE( tohost = 0x00018000 ); + PROVIDE( fromhost = 0xfffffff8 ); } diff --git a/bare-metal-bsp/env/rtl/platform.h b/bare-metal-bsp/env/rtl/platform.h new file mode 100644 index 0000000..59e6fd5 --- /dev/null +++ b/bare-metal-bsp/env/rtl/platform.h @@ -0,0 +1,30 @@ +// See LICENSE for license details. + +#ifndef _ISS_PLATFORM_H +#define _ISS_PLATFORM_H + +// Some things missing from the official encoding.h +#define MCAUSE_INT 0x80000000 +#define MCAUSE_CAUSE 0x7FFFFFFF + +#include "rtl/const.h" +/**************************************************************************** + * Platform definitions + *****************************************************************************/ + +#define MEM_BASE_ADDR _AC(0x00000000,UL) + +// Helper functions +#define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) +#define _REG32P(p, i) ((volatile uint32_t *) ((p) + (i))) + +// Misc + +#include + +void init_pll(void); +unsigned long get_cpu_freq(void); +unsigned long get_timer_freq(void); +uint64_t get_timer_value(void); + +#endif /* _ISS_PLATFORM_H */ diff --git a/hello/bsp/env/start.S b/bare-metal-bsp/env/start.S similarity index 86% rename from hello/bsp/env/start.S rename to bare-metal-bsp/env/start.S index b526411..b57c04d 100644 --- a/hello/bsp/env/start.S +++ b/bare-metal-bsp/env/start.S @@ -5,7 +5,10 @@ .type _start,@function _start: - la gp, _gp +.option push +.option norelax + la gp, __global_pointer$ +.option pop la sp, _sp /* Load data section */ @@ -32,10 +35,11 @@ _start: 2: /* Call global constructors */ +#ifdef HAVE_INIT_FINI la a0, __libc_fini_array call atexit call __libc_init_array - +#endif #ifndef __riscv_float_abi_soft /* Enable FPU */ li t0, MSTATUS_FS @@ -51,4 +55,4 @@ _start: li a0, 0 li a1, 0 call main - tail exit + tail _exit diff --git a/dhrystone/bsp/include/sifive/bits.h b/bare-metal-bsp/include/rtl/bits.h similarity index 100% rename from dhrystone/bsp/include/sifive/bits.h rename to bare-metal-bsp/include/rtl/bits.h diff --git a/bare-metal-bsp/include/rtl/const.h b/bare-metal-bsp/include/rtl/const.h new file mode 100644 index 0000000..7e62f93 --- /dev/null +++ b/bare-metal-bsp/include/rtl/const.h @@ -0,0 +1,27 @@ +#ifndef _RTL_CONST_H +#define _RTL_CONST_H + +#ifdef __ASSEMBLER__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define _AC(X,Y) (X##Y) +#define _AT(T,X) ((T)(X)) +#endif /* !__ASSEMBLER__*/ + +#define _BITUL(x) (_AC(1,UL) << (x)) +#define _BITULL(x) (_AC(1,ULL) << (x)) + +#define UART0_BASE_ADDR 0xffff0000ULL + +#define UART_REG_TXFIFO 0x00 +#define UART_REG_RXFIFO 0x04 +#define UART_REG_TXCTRL 0x08 +#define UART_REG_RXCTRL 0x0c +#define UART_REG_IE 0x10 +#define UART_REG_IP 0x14 +#define UART_REG_DIV 0x18 +#define UART_TXEN 0x1 + +#define UART0_REG(ADDR) *((volatile uint32_t*) (UART0_BASE_ADDR + ADDR)) +#endif /* _RTL_CONST_H */ diff --git a/dhrystone/bsp/include/sifive/sections.h b/bare-metal-bsp/include/rtl/sections.h similarity index 100% rename from dhrystone/bsp/include/sifive/sections.h rename to bare-metal-bsp/include/rtl/sections.h diff --git a/dhrystone/bsp/libwrap/libwrap.mk b/bare-metal-bsp/libwrap/libwrap.mk similarity index 87% rename from dhrystone/bsp/libwrap/libwrap.mk rename to bare-metal-bsp/libwrap/libwrap.mk index 313ed00..fc5e8da 100644 --- a/dhrystone/bsp/libwrap/libwrap.mk +++ b/bare-metal-bsp/libwrap/libwrap.mk @@ -1,7 +1,5 @@ -# See LICENSE for license details. - -ifndef _SIFIVE_MK_LIBWRAP -_SIFIVE_MK_LIBWRAP := # defined +ifndef _MK_LIBWRAP +_MK_LIBWRAP := # defined LIBWRAP_DIR := $(dir $(lastword $(MAKEFILE_LIST))) LIBWRAP_DIR := $(LIBWRAP_DIR:/=) @@ -26,7 +24,8 @@ LIBWRAP_SRCS := \ sys/times.c \ sys/sbrk.c \ sys/_exit.c \ - misc/write_hex.c + misc/write_hex.c \ + sys/printf.c LIBWRAP_SRCS := $(foreach f,$(LIBWRAP_SRCS),$(LIBWRAP_DIR)/$(f)) LIBWRAP_OBJS := $(LIBWRAP_SRCS:.c=.o) @@ -51,4 +50,4 @@ $(LIBWRAP_OBJS): %.o: %.c $(HEADERS) $(LIBWRAP): $(LIBWRAP_OBJS) $(AR) rcs $@ $^ -endif # _SIFIVE_MK_LIBWRAP +endif # _MK_LIBWRAP diff --git a/bare-metal-bsp/libwrap/misc/.gitignore b/bare-metal-bsp/libwrap/misc/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/libwrap/misc/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/dhrystone/bsp/libwrap/misc/write_hex.c b/bare-metal-bsp/libwrap/misc/write_hex.c similarity index 100% rename from dhrystone/bsp/libwrap/misc/write_hex.c rename to bare-metal-bsp/libwrap/misc/write_hex.c diff --git a/bare-metal-bsp/libwrap/stdlib/.gitignore b/bare-metal-bsp/libwrap/stdlib/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/libwrap/stdlib/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/dhrystone/bsp/libwrap/stdlib/malloc.c b/bare-metal-bsp/libwrap/stdlib/malloc.c similarity index 100% rename from dhrystone/bsp/libwrap/stdlib/malloc.c rename to bare-metal-bsp/libwrap/stdlib/malloc.c diff --git a/bare-metal-bsp/libwrap/sys/.gitignore b/bare-metal-bsp/libwrap/sys/.gitignore new file mode 100644 index 0000000..cc5bb74 --- /dev/null +++ b/bare-metal-bsp/libwrap/sys/.gitignore @@ -0,0 +1 @@ +/*.o diff --git a/dhrystone/bsp/libwrap/sys/_exit.c b/bare-metal-bsp/libwrap/sys/_exit.c similarity index 76% rename from dhrystone/bsp/libwrap/sys/_exit.c rename to bare-metal-bsp/libwrap/sys/_exit.c index 7261891..9a5f484 100644 --- a/dhrystone/bsp/libwrap/sys/_exit.c +++ b/bare-metal-bsp/libwrap/sys/_exit.c @@ -3,6 +3,9 @@ #include #include "platform.h" +extern volatile uint32_t tohost; +extern volatile uint32_t fromhost; + void __wrap__exit(int code) { //volatile uint32_t* leds = (uint32_t*) (GPIO_BASE_ADDR + GPIO_OUT_OFFSET); @@ -12,6 +15,7 @@ void __wrap__exit(int code) write(STDERR_FILENO, message, sizeof(message) - 1); write_hex(STDERR_FILENO, code); write(STDERR_FILENO, "\n", 1); - + tohost = code+1; + write(STDERR_FILENO, "\x04", 1); for (;;); } diff --git a/dhrystone/bsp/libwrap/sys/close.c b/bare-metal-bsp/libwrap/sys/close.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/close.c rename to bare-metal-bsp/libwrap/sys/close.c diff --git a/dhrystone/bsp/libwrap/sys/execve.c b/bare-metal-bsp/libwrap/sys/execve.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/execve.c rename to bare-metal-bsp/libwrap/sys/execve.c diff --git a/dhrystone/bsp/libwrap/sys/fork.c b/bare-metal-bsp/libwrap/sys/fork.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/fork.c rename to bare-metal-bsp/libwrap/sys/fork.c diff --git a/dhrystone/bsp/libwrap/sys/fstat.c b/bare-metal-bsp/libwrap/sys/fstat.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/fstat.c rename to bare-metal-bsp/libwrap/sys/fstat.c diff --git a/dhrystone/bsp/libwrap/sys/getpid.c b/bare-metal-bsp/libwrap/sys/getpid.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/getpid.c rename to bare-metal-bsp/libwrap/sys/getpid.c diff --git a/dhrystone/bsp/libwrap/sys/isatty.c b/bare-metal-bsp/libwrap/sys/isatty.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/isatty.c rename to bare-metal-bsp/libwrap/sys/isatty.c diff --git a/dhrystone/bsp/libwrap/sys/kill.c b/bare-metal-bsp/libwrap/sys/kill.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/kill.c rename to bare-metal-bsp/libwrap/sys/kill.c diff --git a/dhrystone/bsp/libwrap/sys/link.c b/bare-metal-bsp/libwrap/sys/link.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/link.c rename to bare-metal-bsp/libwrap/sys/link.c diff --git a/dhrystone/bsp/libwrap/sys/lseek.c b/bare-metal-bsp/libwrap/sys/lseek.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/lseek.c rename to bare-metal-bsp/libwrap/sys/lseek.c diff --git a/dhrystone/bsp/libwrap/sys/open.c b/bare-metal-bsp/libwrap/sys/open.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/open.c rename to bare-metal-bsp/libwrap/sys/open.c diff --git a/dhrystone/bsp/libwrap/sys/openat.c b/bare-metal-bsp/libwrap/sys/openat.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/openat.c rename to bare-metal-bsp/libwrap/sys/openat.c diff --git a/riscv-bldc-forced-commutation/src/wrap_printf.c b/bare-metal-bsp/libwrap/sys/printf.c similarity index 97% rename from riscv-bldc-forced-commutation/src/wrap_printf.c rename to bare-metal-bsp/libwrap/sys/printf.c index af23b1a..4440f53 100644 --- a/riscv-bldc-forced-commutation/src/wrap_printf.c +++ b/bare-metal-bsp/libwrap/sys/printf.c @@ -14,6 +14,13 @@ int putchar(int ch) return write(STDOUT_FILENO, &ch, 1) == 1 ? ch : -1; } +size_t strnlen (const char *str, size_t n) +{ + const char *start = str; + while (n-- > 0 && *str) str++; + return str - start; +} + static void sprintf_putch(int ch, void** data) { char** pstr = (char**)data; diff --git a/dhrystone/bsp/libwrap/sys/read.c b/bare-metal-bsp/libwrap/sys/read.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/read.c rename to bare-metal-bsp/libwrap/sys/read.c diff --git a/dhrystone/bsp/libwrap/sys/sbrk.c b/bare-metal-bsp/libwrap/sys/sbrk.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/sbrk.c rename to bare-metal-bsp/libwrap/sys/sbrk.c diff --git a/dhrystone/bsp/libwrap/sys/stat.c b/bare-metal-bsp/libwrap/sys/stat.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/stat.c rename to bare-metal-bsp/libwrap/sys/stat.c diff --git a/dhrystone/bsp/libwrap/sys/stub.h b/bare-metal-bsp/libwrap/sys/stub.h similarity index 100% rename from dhrystone/bsp/libwrap/sys/stub.h rename to bare-metal-bsp/libwrap/sys/stub.h diff --git a/dhrystone/bsp/libwrap/sys/times.c b/bare-metal-bsp/libwrap/sys/times.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/times.c rename to bare-metal-bsp/libwrap/sys/times.c diff --git a/dhrystone/bsp/libwrap/sys/unlink.c b/bare-metal-bsp/libwrap/sys/unlink.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/unlink.c rename to bare-metal-bsp/libwrap/sys/unlink.c diff --git a/dhrystone/bsp/libwrap/sys/wait.c b/bare-metal-bsp/libwrap/sys/wait.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/wait.c rename to bare-metal-bsp/libwrap/sys/wait.c diff --git a/dhrystone/bsp/libwrap/sys/write.c b/bare-metal-bsp/libwrap/sys/write.c similarity index 100% rename from dhrystone/bsp/libwrap/sys/write.c rename to bare-metal-bsp/libwrap/sys/write.c diff --git a/benchmarks/coremark/cm b/benchmarks/coremark/cm new file mode 160000 --- /dev/null +++ b/benchmarks/coremark/cm @@ -0,0 +1 @@ +Subproject commit 0000000000000000000000000000000000000000 diff --git a/benchmarks/coremark/tgc/core_portme.c b/benchmarks/coremark/tgc/core_portme.c new file mode 100644 index 0000000..56639c7 --- /dev/null +++ b/benchmarks/coremark/tgc/core_portme.c @@ -0,0 +1,197 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Original Author: Shay Gal-on +*/ +#include "coremark.h" +#include "core_portme.h" +//Read cycle CSR +unsigned long long _read_cycle() +{ + unsigned long long result; + unsigned long lower; + unsigned long upper1; + unsigned long upper2; + + asm volatile ( + "repeat_cycle_%=: csrr %0, cycleh;\n" + " csrr %1, cycle;\n" + " csrr %2, cycleh;\n" + " bne %0, %2, repeat_cycle_%=;\n" + : "=r" (upper1),"=r" (lower),"=r" (upper2) // Outputs : temp variable for load result + : + : + ); + *(unsigned long *)(&result) = lower; + *((unsigned long *)(&result)+1) = upper1; + + return result; +} + +volatile int tohost; +volatile int fromhost; + +void exit(int n){ + tohost = 0x1; + for (;;); +} + +void __libc_init_array (void) { +/* + size_t count; + size_t i; + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i] (); + +#ifdef HAVE_INIT_FINI + _init (); +#endif + + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i] (); +*/ +} +#if VALIDATION_RUN +volatile ee_s32 seed1_volatile = 0x3415; +volatile ee_s32 seed2_volatile = 0x3415; +volatile ee_s32 seed3_volatile = 0x66; +#endif +#if PERFORMANCE_RUN +volatile ee_s32 seed1_volatile = 0x0; +volatile ee_s32 seed2_volatile = 0x0; +volatile ee_s32 seed3_volatile = 0x66; +#endif +#if PROFILE_RUN +volatile ee_s32 seed1_volatile = 0x8; +volatile ee_s32 seed2_volatile = 0x8; +volatile ee_s32 seed3_volatile = 0x8; +#endif +volatile ee_s32 seed4_volatile = ITERATIONS; +volatile ee_s32 seed5_volatile = 0; +/* Porting : Timing functions + How to capture time and convert to seconds must be ported to whatever is + supported by the platform. e.g. Read value from on board RTC, read value from + cpu clock cycles performance counter etc. Sample implementation for standard + time.h and windows.h definitions included. +*/ +CORETIMETYPE +barebones_clock() +{ + return (CORETIMETYPE)_read_cycle(); +} +/* Define : TIMER_RES_DIVIDER + Divider to trade off timer resolution and total time that can be + measured. + + Use lower values to increase resolution, but make sure that overflow + does not occur. If there are issues with the return value overflowing, + increase this value. + */ +#define GETMYTIME(_t) (*_t = barebones_clock()) +#define MYTIMEDIFF(fin, ini) ((fin) - (ini)) +#define TIMER_RES_DIVIDER 1 +#define SAMPLE_TIME_IMPLEMENTATION 1 +#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER) + +/** Define Host specific (POSIX), or target specific global time variables. */ +static CORETIMETYPE start_time_val, stop_time_val; + +/* Function : start_time + This function will be called right before starting the timed portion of + the benchmark. + + Implementation may be capturing a system timer (as implemented in the + example code) or zeroing some system parameters - e.g. setting the cpu clocks + cycles to 0. +*/ +void +start_time(void) +{ + GETMYTIME(&start_time_val); +} +/* Function : stop_time + This function will be called right after ending the timed portion of the + benchmark. + + Implementation may be capturing a system timer (as implemented in the + example code) or other system parameters - e.g. reading the current value of + cpu cycles counter. +*/ +void +stop_time(void) +{ + GETMYTIME(&stop_time_val); +} +/* Function : get_time + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other + value, as long as it can be converted to seconds by . This + methodology is taken to accomodate any hardware or simulated platform. The + sample implementation returns millisecs by default, and the resolution is + controlled by +*/ +CORE_TICKS +get_time(void) +{ + CORE_TICKS elapsed + = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); + return elapsed; +} +/* Function : time_in_secs + Convert the value returned by get_time to seconds. + + The type is used to accomodate systems with no support for + floating point. Default implementation implemented by the EE_TICKS_PER_SEC + macro above. +*/ +secs_ret +time_in_secs(CORE_TICKS ticks) +{ + secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; + return retval; +} + +ee_u32 default_num_contexts = 1; + +/* Function : portable_init + Target specific initialization code + Test for some common mistakes. +*/ +void +portable_init(core_portable *p, int *argc, char *argv[]) +{ + if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) + { + ee_printf( + "ERROR! Please define ee_ptr_int to a type that holds a " + "pointer!\n"); + } + if (sizeof(ee_u32) != 4) + { + ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); + } + p->portable_id = 1; +} +/* Function : portable_fini + Target specific final code +*/ +void +portable_fini(core_portable *p) +{ + p->portable_id = 0; +} diff --git a/benchmarks/coremark/tgc/core_portme.h b/benchmarks/coremark/tgc/core_portme.h new file mode 100644 index 0000000..cf0f769 --- /dev/null +++ b/benchmarks/coremark/tgc/core_portme.h @@ -0,0 +1,210 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Original Author: Shay Gal-on +*/ +/* Topic : Description + This file contains configuration constants required to execute on + different platforms +*/ +#ifndef CORE_PORTME_H +#define CORE_PORTME_H +/************************/ +/* Data types and settings */ +/************************/ +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. +*/ +#ifndef HAS_FLOAT +#define HAS_FLOAT 0 +#endif +/* Configuration : HAS_TIME_H + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef HAS_TIME_H +#define HAS_TIME_H 0 +#endif +/* Configuration : USE_CLOCK + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef USE_CLOCK +#define USE_CLOCK 0 +#endif +/* Configuration : HAS_STDIO + Define to 1 if the platform has stdio.h. +*/ +#ifndef HAS_STDIO +#define HAS_STDIO 0 +#endif +/* Configuration : HAS_PRINTF + Define to 1 if the platform has stdio.h and implements the printf + function. +*/ +#ifndef HAS_PRINTF +#define HAS_PRINTF 0 +#endif + +/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION + Initialize these strings per platform +*/ +#ifndef COMPILER_VERSION +#ifdef __GNUC__ +#define COMPILER_VERSION "GCC"__VERSION__ +#else +#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" +#endif +#endif +#ifndef COMPILER_FLAGS +#define COMPILER_FLAGS \ + FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ +#endif +#ifndef MEM_LOCATION +#define MEM_LOCATION "STACK" +#endif + +/* Data Types : + To avoid compiler issues, define the data types that need ot be used for + 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise + coremark may fail!!! +*/ +typedef signed short ee_s16; +typedef unsigned short ee_u16; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef ee_u32 ee_ptr_int; +typedef ee_u32 ee_size_t; +#define NULL ((void *)0) +/* align_mem : + This macro is used to align an offset to point to a 32b value. It is + used in the Matrix algorithm to initialize the input memory blocks. +*/ +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3)) + +/* Configuration : CORE_TICKS + Define type of return from the timing functions. + */ +#define CORETIMETYPE ee_u32 +typedef ee_u32 CORE_TICKS; + +/* Configuration : SEED_METHOD + Defines method to get seed values that cannot be computed at compile + time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. +*/ +#ifndef SEED_METHOD +#define SEED_METHOD SEED_VOLATILE +#endif + +/* Configuration : MEM_METHOD + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). +*/ +#ifndef MEM_METHOD +#define MEM_METHOD MEM_STACK +#endif + +/* Configuration : MULTITHREAD + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching + parallel contexts must be defined. + + Two sample implementations are provided. Use or + to enable them. + + It is valid to have a different implementation of + and in , to fit a particular architecture. +*/ +#ifndef MULTITHREAD +#define MULTITHREAD 1 +#define USE_PTHREAD 0 +#define USE_FORK 0 +#define USE_SOCKET 0 +#endif + +/* Configuration : MAIN_HAS_NOARGC + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. +*/ +#ifndef MAIN_HAS_NOARGC +#define MAIN_HAS_NOARGC 0 +#endif + +/* Configuration : MAIN_HAS_NORETURN + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main +*/ +#ifndef MAIN_HAS_NORETURN +#define MAIN_HAS_NORETURN 0 +#endif + +/* Variable : default_num_contexts + Not used for this simple port, must cintain the value 1. +*/ +extern ee_u32 default_num_contexts; + +typedef struct CORE_PORTABLE_S +{ + ee_u8 portable_id; +} core_portable; + +/* target specific init/fini */ +void portable_init(core_portable *p, int *argc, char *argv[]); +void portable_fini(core_portable *p); + +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \ + && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE == 1200) +#define PROFILE_RUN 1 +#elif (TOTAL_DATA_SIZE == 2000) +#define PERFORMANCE_RUN 1 +#else +#define VALIDATION_RUN 1 +#endif +#endif + +int ee_printf(const char *fmt, ...); + +#endif /* CORE_PORTME_H */ diff --git a/benchmarks/coremark/tgc/core_portme.mak b/benchmarks/coremark/tgc/core_portme.mak new file mode 100755 index 0000000..c2802d9 --- /dev/null +++ b/benchmarks/coremark/tgc/core_portme.mak @@ -0,0 +1,94 @@ +# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Original Author: Shay Gal-on + +#File : core_portme.mak +ISA?=imc +RISCV_ARCH:=rv32$(ISA) +RISCV_ABI:=ilp32 + +# Flag : OUTFLAG +# Use this flag to define how to to get an executable (e.g -o) +OUTFLAG= -o +# Flag : CC +# Use this flag to define compiler to use +CC = riscv32-unknown-elf-gcc +# Flag : LD +# Use this flag to define compiler to use +LD = riscv32-unknown-elf-gcc +# Flag : AS +# Use this flag to define compiler to use +AS = riscv32-unknown-elf-as +# Flag : CFLAGS +# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags" +PORT_CFLAGS = -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -O3 -DCLOCKS_PER_SEC=10000000 -nostdlib -nostartfiles -nodefaultlibs \ + -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -flto +FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)" +CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\" +#Flag : LFLAGS_END +# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts). +# Note : On certain platforms, the default clock_gettime implementation is supported but requires linking of librt. +SEPARATE_COMPILE=1 +# Flag : SEPARATE_COMPILE +# You must also define below how to create an object file, and how to link. +OBJOUT = -o +LFLAGS = +#--specs=nano.specs -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) +ASFLAGS = +OFLAG = -o +COUT = -c + +LFLAGS_END = +# Flag : PORT_SRCS +# Port specific source files can be added here +# You may also need cvt.c if the fcvt functions are not provided as intrinsics by your compiler! +PORT_SRCS = $(PORT_DIR)/core_portme.c $(PORT_DIR)/ee_printf.c +vpath %.c $(PORT_DIR) +vpath %.s $(PORT_DIR) +PORT_OBJS = core_portme.o ee_printf.o +# Flag : LOAD +# For a simple port, we assume self hosted compile and run, no load needed. + +# Flag : RUN +# For a simple port, we assume self hosted compile and run, simple invocation of the executable + +LOAD = echo "" +RUN = echo "" + +OEXT = .o +EXE = .elf + +$(OPATH)$(PORT_DIR)/%$(OEXT) : %.c + $(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@ + +$(OPATH)%$(OEXT) : %.c + $(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@ + +$(OPATH)$(PORT_DIR)/%$(OEXT) : %.s + $(AS) $(ASFLAGS) $< $(OBJOUT) $@ + +# Target : port_pre% and port_post% +# For the purpose of this simple port, no pre or post steps needed. + +.PHONY : port_prebuild port_postbuild port_prerun port_postrun port_preload port_postload +port_pre% port_post% : + +# FLAG : OPATH +# Path to the output folder. Default - current folder. +OPATH = ./ +MKDIR = mkdir -p + +dist-clean: clean + rm -f *.o diff --git a/benchmarks/coremark/tgc/cvt.c b/benchmarks/coremark/tgc/cvt.c new file mode 100644 index 0000000..333e8ea --- /dev/null +++ b/benchmarks/coremark/tgc/cvt.c @@ -0,0 +1,127 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#define CVTBUFSIZE 80 +static char CVTBUF[CVTBUFSIZE]; + +static char * +cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag) +{ + int r2; + double fi, fj; + char * p, *p1; + + if (ndigits < 0) + ndigits = 0; + if (ndigits >= CVTBUFSIZE - 1) + ndigits = CVTBUFSIZE - 2; + r2 = 0; + *sign = 0; + p = &buf[0]; + if (arg < 0) + { + *sign = 1; + arg = -arg; + } + arg = modf(arg, &fi); + p1 = &buf[CVTBUFSIZE]; + + if (fi != 0) + { + p1 = &buf[CVTBUFSIZE]; + while (fi != 0) + { + fj = modf(fi / 10, &fi); + *--p1 = (int)((fj + .03) * 10) + '0'; + r2++; + } + while (p1 < &buf[CVTBUFSIZE]) + *p++ = *p1++; + } + else if (arg > 0) + { + while ((fj = arg * 10) < 1) + { + arg = fj; + r2--; + } + } + p1 = &buf[ndigits]; + if (eflag == 0) + p1 += r2; + *decpt = r2; + if (p1 < &buf[0]) + { + buf[0] = '\0'; + return buf; + } + while (p <= p1 && p < &buf[CVTBUFSIZE]) + { + arg *= 10; + arg = modf(arg, &fj); + *p++ = (int)fj + '0'; + } + if (p1 >= &buf[CVTBUFSIZE]) + { + buf[CVTBUFSIZE - 1] = '\0'; + return buf; + } + p = p1; + *p1 += 5; + while (*p1 > '9') + { + *p1 = '0'; + if (p1 > buf) + ++*--p1; + else + { + *p1 = '1'; + (*decpt)++; + if (eflag == 0) + { + if (p > buf) + *p = '0'; + p++; + } + } + } + *p = '\0'; + return buf; +} + +char * +ecvt(double arg, int ndigits, int *decpt, int *sign) +{ + return cvt(arg, ndigits, decpt, sign, CVTBUF, 1); +} + +char * +ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) +{ + return cvt(arg, ndigits, decpt, sign, buf, 1); +} + +char * +fcvt(double arg, int ndigits, int *decpt, int *sign) +{ + return cvt(arg, ndigits, decpt, sign, CVTBUF, 0); +} + +char * +fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) +{ + return cvt(arg, ndigits, decpt, sign, buf, 0); +} diff --git a/benchmarks/coremark/tgc/ee_printf.c b/benchmarks/coremark/tgc/ee_printf.c new file mode 100644 index 0000000..161f582 --- /dev/null +++ b/benchmarks/coremark/tgc/ee_printf.c @@ -0,0 +1,701 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +#define ZEROPAD (1 << 0) /* Pad with zero */ +#define SIGN (1 << 1) /* Unsigned/signed long */ +#define PLUS (1 << 2) /* Show plus */ +#define SPACE (1 << 3) /* Spacer */ +#define LEFT (1 << 4) /* Left justified */ +#define HEX_PREP (1 << 5) /* 0x */ +#define UPPERCASE (1 << 6) /* 'ABCDEF' */ + +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static char * digits = "0123456789abcdefghijklmnopqrstuvwxyz"; +static char * upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static ee_size_t strnlen(const char *s, ee_size_t count); + +static ee_size_t +strnlen(const char *s, ee_size_t count) +{ + const char *sc; + for (sc = s; *sc != '\0' && count--; ++sc) + ; + return sc - s; +} + +static int +skip_atoi(const char **s) +{ + int i = 0; + while (is_digit(**s)) + i = i * 10 + *((*s)++) - '0'; + return i; +} + +static char * +number(char *str, long num, int base, int size, int precision, int type) +{ + char c, sign, tmp[66]; + char *dig = digits; + int i; + + if (type & UPPERCASE) + dig = upper_digits; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) + { + if (num < 0) + { + sign = '-'; + num = -num; + size--; + } + else if (type & PLUS) + { + sign = '+'; + size--; + } + else if (type & SPACE) + { + sign = ' '; + size--; + } + } + + if (type & HEX_PREP) + { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + + i = 0; + + if (num == 0) + tmp[i++] = '0'; + else + { + while (num != 0) + { + tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; + num = ((unsigned long)num) / (unsigned)base; + } + } + + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD | LEFT))) + while (size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + + if (type & HEX_PREP) + { + if (base == 8) + *str++ = '0'; + else if (base == 16) + { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + + return str; +} + +static char * +eaddr(char *str, unsigned char *addr, int size, int precision, int type) +{ + char tmp[24]; + char *dig = digits; + int i, len; + + if (type & UPPERCASE) + dig = upper_digits; + len = 0; + for (i = 0; i < 6; i++) + { + if (i != 0) + tmp[len++] = ':'; + tmp[len++] = dig[addr[i] >> 4]; + tmp[len++] = dig[addr[i] & 0x0F]; + } + + if (!(type & LEFT)) + while (len < size--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = tmp[i]; + while (len < size--) + *str++ = ' '; + + return str; +} + +static char * +iaddr(char *str, unsigned char *addr, int size, int precision, int type) +{ + char tmp[24]; + int i, n, len; + + len = 0; + for (i = 0; i < 4; i++) + { + if (i != 0) + tmp[len++] = '.'; + n = addr[i]; + + if (n == 0) + tmp[len++] = digits[0]; + else + { + if (n >= 100) + { + tmp[len++] = digits[n / 100]; + n = n % 100; + tmp[len++] = digits[n / 10]; + n = n % 10; + } + else if (n >= 10) + { + tmp[len++] = digits[n / 10]; + n = n % 10; + } + + tmp[len++] = digits[n]; + } + } + + if (!(type & LEFT)) + while (len < size--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = tmp[i]; + while (len < size--) + *str++ = ' '; + + return str; +} + +#if HAS_FLOAT + +char * ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); +char * fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); +static void ee_bufcpy(char *d, char *s, int count); + +void +ee_bufcpy(char *pd, char *ps, int count) +{ + char *pe = ps + count; + while (ps != pe) + *pd++ = *ps++; +} + +static void +parse_float(double value, char *buffer, char fmt, int precision) +{ + int decpt, sign, exp, pos; + char *digits = NULL; + char cvtbuf[80]; + int capexp = 0; + int magnitude; + + if (fmt == 'G' || fmt == 'E') + { + capexp = 1; + fmt += 'a' - 'A'; + } + + if (fmt == 'g') + { + digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); + magnitude = decpt - 1; + if (magnitude < -4 || magnitude > precision - 1) + { + fmt = 'e'; + precision -= 1; + } + else + { + fmt = 'f'; + precision -= decpt; + } + } + + if (fmt == 'e') + { + digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf); + + if (sign) + *buffer++ = '-'; + *buffer++ = *digits; + if (precision > 0) + *buffer++ = '.'; + ee_bufcpy(buffer, digits + 1, precision); + buffer += precision; + *buffer++ = capexp ? 'E' : 'e'; + + if (decpt == 0) + { + if (value == 0.0) + exp = 0; + else + exp = -1; + } + else + exp = decpt - 1; + + if (exp < 0) + { + *buffer++ = '-'; + exp = -exp; + } + else + *buffer++ = '+'; + + buffer[2] = (exp % 10) + '0'; + exp = exp / 10; + buffer[1] = (exp % 10) + '0'; + exp = exp / 10; + buffer[0] = (exp % 10) + '0'; + buffer += 3; + } + else if (fmt == 'f') + { + digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf); + if (sign) + *buffer++ = '-'; + if (*digits) + { + if (decpt <= 0) + { + *buffer++ = '0'; + *buffer++ = '.'; + for (pos = 0; pos < -decpt; pos++) + *buffer++ = '0'; + while (*digits) + *buffer++ = *digits++; + } + else + { + pos = 0; + while (*digits) + { + if (pos++ == decpt) + *buffer++ = '.'; + *buffer++ = *digits++; + } + } + } + else + { + *buffer++ = '0'; + if (precision > 0) + { + *buffer++ = '.'; + for (pos = 0; pos < precision; pos++) + *buffer++ = '0'; + } + } + } + + *buffer = '\0'; +} + +static void +decimal_point(char *buffer) +{ + while (*buffer) + { + if (*buffer == '.') + return; + if (*buffer == 'e' || *buffer == 'E') + break; + buffer++; + } + + if (*buffer) + { + int n = strnlen(buffer, 256); + while (n > 0) + { + buffer[n + 1] = buffer[n]; + n--; + } + + *buffer = '.'; + } + else + { + *buffer++ = '.'; + *buffer = '\0'; + } +} + +static void +cropzeros(char *buffer) +{ + char *stop; + + while (*buffer && *buffer != '.') + buffer++; + if (*buffer++) + { + while (*buffer && *buffer != 'e' && *buffer != 'E') + buffer++; + stop = buffer--; + while (*buffer == '0') + buffer--; + if (*buffer == '.') + buffer--; + while (buffer != stop) + *++buffer = 0; + } +} + +static char * +flt(char *str, double num, int size, int precision, char fmt, int flags) +{ + char tmp[80]; + char c, sign; + int n, i; + + // Left align means no zero padding + if (flags & LEFT) + flags &= ~ZEROPAD; + + // Determine padding and sign char + c = (flags & ZEROPAD) ? '0' : ' '; + sign = 0; + if (flags & SIGN) + { + if (num < 0.0) + { + sign = '-'; + num = -num; + size--; + } + else if (flags & PLUS) + { + sign = '+'; + size--; + } + else if (flags & SPACE) + { + sign = ' '; + size--; + } + } + + // Compute the precision value + if (precision < 0) + precision = 6; // Default precision: 6 + + // Convert floating point number to text + parse_float(num, tmp, fmt, precision); + + if ((flags & HEX_PREP) && precision == 0) + decimal_point(tmp); + if (fmt == 'g' && !(flags & HEX_PREP)) + cropzeros(tmp); + + n = strnlen(tmp, 256); + + // Output number with alignment and padding + size -= n; + if (!(flags & (ZEROPAD | LEFT))) + while (size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (!(flags & LEFT)) + while (size-- > 0) + *str++ = c; + for (i = 0; i < n; i++) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + + return str; +} + +#endif + +static int +ee_vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + unsigned long num; + int i, base; + char * str; + char * s; + + int flags; // Flags to number() + + int field_width; // Width of output field + int precision; // Min. # of digits for integers; max number of chars for + // from string + int qualifier; // 'h', 'l', or 'L' for integer fields + + for (str = buf; *fmt; fmt++) + { + if (*fmt != '%') + { + *str++ = *fmt; + continue; + } + + // Process flags + flags = 0; + repeat: + fmt++; // This also skips first '%' + switch (*fmt) + { + case '-': + flags |= LEFT; + goto repeat; + case '+': + flags |= PLUS; + goto repeat; + case ' ': + flags |= SPACE; + goto repeat; + case '#': + flags |= HEX_PREP; + goto repeat; + case '0': + flags |= ZEROPAD; + goto repeat; + } + + // Get field width + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') + { + fmt++; + field_width = va_arg(args, int); + if (field_width < 0) + { + field_width = -field_width; + flags |= LEFT; + } + } + + // Get the precision + precision = -1; + if (*fmt == '.') + { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') + { + ++fmt; + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + // Get the conversion qualifier + qualifier = -1; + if (*fmt == 'l' || *fmt == 'L') + { + qualifier = *fmt; + fmt++; + } + + // Default base + base = 10; + + switch (*fmt) + { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char)va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + len = strnlen(s, precision); + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) + { + field_width = 2 * sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long)va_arg(args, void *), + 16, + field_width, + precision, + flags); + continue; + + case 'A': + flags |= UPPERCASE; + + case 'a': + if (qualifier == 'l') + str = eaddr(str, + va_arg(args, unsigned char *), + field_width, + precision, + flags); + else + str = iaddr(str, + va_arg(args, unsigned char *), + field_width, + precision, + flags); + continue; + + // Integer number formats - set up the flags and "break" + case 'o': + base = 8; + break; + + case 'X': + flags |= UPPERCASE; + + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + + case 'u': + break; + +#if HAS_FLOAT + + case 'f': + str = flt(str, + va_arg(args, double), + field_width, + precision, + *fmt, + flags | SIGN); + continue; + +#endif + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + + str = number(str, num, base, field_width, precision, flags); + } + + *str = '\0'; + return str - buf; +} + +#define UART0_BASE_ADDR 0xffff0000ULL + +#define UART_REG_TXFIFO 0x00 +#define UART_REG_RXFIFO 0x04 +#define UART_REG_TXCTRL 0x08 +#define UART_REG_RXCTRL 0x0c +#define UART_REG_IE 0x10 +#define UART_REG_IP 0x14 +#define UART_REG_DIV 0x18 +#define UART_TXEN 0x1 + +#define UART0_REG(ADDR) *((ee_u32*) (UART0_BASE_ADDR + ADDR)) + +void +uart_send_char(char c) +{ + while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; + UART0_REG(UART_REG_TXFIFO) = (unsigned char)c; +} + +int +ee_printf(const char *fmt, ...) +{ + char buf[1024], *p; + va_list args; + int n = 0; + + va_start(args, fmt); + ee_vsprintf(buf, fmt, args); + va_end(args); + p = buf; + while (*p) + { + uart_send_char(*p); + n++; + p++; + } + + return n; +} diff --git a/benchmarks/coremark/tgc/tgc.lds b/benchmarks/coremark/tgc/tgc.lds new file mode 100644 index 0000000..08de74d --- /dev/null +++ b/benchmarks/coremark/tgc/tgc.lds @@ -0,0 +1,241 @@ +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) +MEMORY +{ + RAM (rwx) : ORIGIN = 0x0, LENGTH = 128M +} + +ENTRY(_start) + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rela.plt : + { + *(.rela.plt) + } + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .init : + { + KEEP (*(SORT_NONE(.init))) + *crt0.o(.text .text.*) + } > RAM + .text : + { + *(.text.init) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : + { + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } + .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } + /* These sections are generated by the Sun/Oracle C++ compiler. */ + .exception_ranges : ONLY_IF_RO { *(.exception_ranges*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) } + .gnu_extab : ONLY_IF_RW { *(.gnu_extab) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + .exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } + /* Thread Local Storage sections */ + .tdata : + { + PROVIDE_HIDDEN (__tdata_start = .); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .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 = .); + } + .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 = .); + } + .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)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + . = DATA_SEGMENT_RELRO_END (0, .); + .data : + { + __DATA_BEGIN__ = .; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + __SDATA_BEGIN__ = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + _edata = .; PROVIDE (edata = .); + . = .; + __bss_start = .; + .sbss : + { + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we do not + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + . = ALIGN(32 / 8); + . = SEGMENT_START("ldata-segment", .); + . = ALIGN(32 / 8); + __BSS_END__ = .; + __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, + MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); + _end = .; PROVIDE (end = .); + . = DATA_SEGMENT_END (.); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF Extension. */ + .debug_macro 0 : { *(.debug_macro) } + .debug_addr 0 : { *(.debug_addr) } + .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/dhrystone/.cproject b/benchmarks/dhrystone/.cproject similarity index 100% rename from dhrystone/.cproject rename to benchmarks/dhrystone/.cproject diff --git a/dhrystone/.gdbinit b/benchmarks/dhrystone/.gdbinit similarity index 100% rename from dhrystone/.gdbinit rename to benchmarks/dhrystone/.gdbinit diff --git a/dhrystone/.gitignore b/benchmarks/dhrystone/.gitignore similarity index 100% rename from dhrystone/.gitignore rename to benchmarks/dhrystone/.gitignore diff --git a/dhrystone/.project b/benchmarks/dhrystone/.project similarity index 100% rename from dhrystone/.project rename to benchmarks/dhrystone/.project diff --git a/benchmarks/dhrystone/Makefile b/benchmarks/dhrystone/Makefile new file mode 100644 index 0000000..b6750e8 --- /dev/null +++ b/benchmarks/dhrystone/Makefile @@ -0,0 +1,25 @@ +TARGET := dhrystone +ISA?=imc + +ASM_SRCS := +C_SRCS := dhry_stubs.c dhry_printf.c dhry_1.c dhry_2.c +HEADERS := dhry.h + +BOARD=iss +LINK_TARGET=link +RISCV_ARCH:=rv32$(ISA) +ifeq ($(ISA),e) + RISCV_ABI:=ilp32e +else + RISCV_ABI:=ilp32 +endif +# '-lgcc -lm' are needed to add softfloat routines +CFLAGS := -g -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=medlow -O3 -DHZ=32768 -DTIME -DNO_INIT -fno-inline -fno-builtin-printf -fno-common -Wno-implicit \ + -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las +LDFLAGS := -g -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) -mcmodel=medlow -Wl,--wrap=scanf -Wl,--wrap=printf -Wl,--wrap=exit -lgcc -lm + +TOOL_DIR=$(dir $(compiler)) + +TRIPLET=riscv32-unknown-elf +BSP_BASE = ../../bare-metal-bsp +include $(BSP_BASE)/env/common-gcc.mk diff --git a/dhrystone/dhry.h b/benchmarks/dhrystone/dhry.h similarity index 100% rename from dhrystone/dhry.h rename to benchmarks/dhrystone/dhry.h diff --git a/dhrystone/dhry_1.c b/benchmarks/dhrystone/dhry_1.c similarity index 98% rename from dhrystone/dhry_1.c rename to benchmarks/dhrystone/dhry_1.c index 66571fb..5255fe3 100644 --- a/dhrystone/dhry_1.c +++ b/benchmarks/dhrystone/dhry_1.c @@ -16,6 +16,7 @@ */ #include "dhry.h" +extern char* strcpy(char* dest, const char* src); /* Global Variables: */ @@ -258,9 +259,9 @@ main () else { #ifdef TIME - Microseconds = (float) User_Time * Mic_secs_Per_Second + Microseconds = ((float) User_Time/(float)HZ) * Mic_secs_Per_Second / (float) Number_Of_Runs; - Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time; + Dhrystones_Per_Second = (float) Number_Of_Runs / ((float) User_Time/(float)HZ); #else Microseconds = (float) User_Time * Mic_secs_Per_Second / ((float) HZ * ((float) Number_Of_Runs)); diff --git a/dhrystone/dhry_2.c b/benchmarks/dhrystone/dhry_2.c similarity index 100% rename from dhrystone/dhry_2.c rename to benchmarks/dhrystone/dhry_2.c diff --git a/benchmarks/dhrystone/dhry_printf.c b/benchmarks/dhrystone/dhry_printf.c new file mode 100644 index 0000000..d1c6b0c --- /dev/null +++ b/benchmarks/dhrystone/dhry_printf.c @@ -0,0 +1,15 @@ +/* The functions in this file are only meant to support Dhrystone on an + * embedded RV32 system and are obviously incorrect in general. */ + +#include +#include +#include +#include +#include +#include + +//#undef putchar +//int putchar(int ch) +//{ +// return write(1, &ch, 1) == 1 ? ch : -1; +//} diff --git a/dhrystone/dhry_stubs.c b/benchmarks/dhrystone/dhry_stubs.c similarity index 71% rename from dhrystone/dhry_stubs.c rename to benchmarks/dhrystone/dhry_stubs.c index 9ae1160..d8a1eb7 100644 --- a/dhrystone/dhry_stubs.c +++ b/benchmarks/dhrystone/dhry_stubs.c @@ -5,18 +5,16 @@ long time(void) { - return get_timer_value() / get_timer_freq(); + return get_timer_value(); } // set the number of dhrystone iterations void __wrap_scanf(const char* fmt, int* n) { -// *n = 100000000; - *n = 1000000; + *n = 200000; } -volatile uint64_t tohost; -volatile uint64_t fromhost; +extern volatile uint32_t tohost; void __wrap_exit(int n){ tohost = 0x1; diff --git a/benchmarks/dhrystone/dhrystone.dis b/benchmarks/dhrystone/dhrystone.dis new file mode 100644 index 0000000..f87ecee --- /dev/null +++ b/benchmarks/dhrystone/dhrystone.dis @@ -0,0 +1,3946 @@ + +dhrystone: file format elf32-littleriscv + + +Disassembly of section .init: + +00000020 <_start>: + .type _start,@function + +_start: +.option push +.option norelax + la gp, __global_pointer$ + 20: 10000197 auipc gp,0x10000 + 24: 7f018193 addi gp,gp,2032 # 10000810 <__global_pointer$> +.option pop + la sp, _sp + 28: 10004117 auipc sp,0x10004 + 2c: fd810113 addi sp,sp,-40 # 10004000 <_sp> + + /* Load data section */ + la a0, _data_lma + 30: 00003517 auipc a0,0x3 + 34: e7450513 addi a0,a0,-396 # 2ea4 <_data_lma> + la a1, _data + 38: 10000597 auipc a1,0x10000 + 3c: fc858593 addi a1,a1,-56 # 10000000 <__DATA_BEGIN__> + la a2, _edata + 40: 10000617 auipc a2,0x10000 + 44: fd460613 addi a2,a2,-44 # 10000014 + bgeu a1, a2, 2f + 48: 00c5fc63 bgeu a1,a2,60 <_start+0x40> +1: + lw t0, (a0) + 4c: 00052283 lw t0,0(a0) + sw t0, (a1) + 50: 0055a023 sw t0,0(a1) + addi a0, a0, 4 + 54: 00450513 addi a0,a0,4 + addi a1, a1, 4 + 58: 00458593 addi a1,a1,4 + bltu a1, a2, 1b + 5c: fec5e8e3 bltu a1,a2,4c <_start+0x2c> +2: + + /* Clear bss section */ + la a0, __bss_start + 60: 10000517 auipc a0,0x10000 + 64: fb450513 addi a0,a0,-76 # 10000014 + la a1, _end + 68: 10002597 auipc a1,0x10002 + 6c: 7b058593 addi a1,a1,1968 # 10002818 <__BSS_END__> + bgeu a0, a1, 2f + 70: 00b57863 bgeu a0,a1,80 <_start+0x60> +1: + sw zero, (a0) + 74: 00052023 sw zero,0(a0) + addi a0, a0, 4 + 78: 00450513 addi a0,a0,4 + bltu a0, a1, 1b + 7c: feb56ce3 bltu a0,a1,74 <_start+0x54> + fssr x0 +1: +#endif + + /* argc = argv = 0 */ + li a0, 0 + 80: 00000513 li a0,0 + li a1, 0 + 84: 00000593 li a1,0 + call main + 88: 008000ef jal ra,90
+ tail _exit + 8c: 5640106f j 15f0 <__wrap__exit> + +Disassembly of section .text: + +00000090
: +main () +/*****/ + + /* main program, corresponds to procedures */ + /* Main and Proc_0 in the Ada version */ +{ + 90: 7135 addi sp,sp,-160 + REG int Run_Index; + REG int Number_Of_Runs; + + /* Initializations */ + + Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + 92: 03000513 li a0,48 +{ + 96: cf06 sw ra,156(sp) + 98: cd22 sw s0,152(sp) + 9a: c94a sw s2,144(sp) + 9c: c74e sw s3,140(sp) + 9e: c552 sw s4,136(sp) + a0: c356 sw s5,132(sp) + a2: c15a sw s6,128(sp) + a4: dede sw s7,124(sp) + a6: dce2 sw s8,120(sp) + a8: dae6 sw s9,116(sp) + aa: d8ea sw s10,112(sp) + ac: d6ee sw s11,108(sp) + ae: cb26 sw s1,148(sp) + Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + b0: 440010ef jal ra,14f0 <__wrap_malloc> + b4: 842a mv s0,a0 + b6: 82818793 addi a5,gp,-2008 # 10000038 + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + ba: 03000513 li a0,48 + Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + be: c380 sw s0,0(a5) + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + c0: 430010ef jal ra,14f0 <__wrap_malloc> + + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; + Ptr_Glob->Discr = Ident_1; + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + Ptr_Glob->variant.var_1.Int_Comp = 40; + strcpy (Ptr_Glob->variant.var_1.Str_Comp, + c4: 00002717 auipc a4,0x2 + c8: 50470713 addi a4,a4,1284 # 25c8 <__modsi3+0x30> + "DHRYSTONE PROGRAM, SOME STRING"); + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + cc: 00003917 auipc s2,0x3 + d0: a9890913 addi s2,s2,-1384 # 2b64 <__modsi3+0x5cc> + strcpy (Ptr_Glob->variant.var_1.Str_Comp, + d4: 00072283 lw t0,0(a4) + d8: 00472e83 lw t4,4(a4) + dc: 00872e03 lw t3,8(a4) + e0: 00c72303 lw t1,12(a4) + e4: 01072883 lw a7,16(a4) + e8: 01472803 lw a6,20(a4) + ec: 4f0c lw a1,24(a4) + ee: 01c75603 lhu a2,28(a4) + f2: 01e74683 lbu a3,30(a4) + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + f6: 00092f83 lw t6,0(s2) + fa: 00492f03 lw t5,4(s2) + fe: 00892983 lw s3,8(s2) + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + 102: 4389 li t2,2 + Ptr_Glob->variant.var_1.Int_Comp = 40; + 104: 02800a13 li s4,40 + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + 108: 82c18a93 addi s5,gp,-2004 # 1000003c + Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; + 10c: 00752423 sw t2,8(a0) + strcpy (Ptr_Glob->variant.var_1.Str_Comp, + 110: 00552823 sw t0,16(a0) + 114: 01d52a23 sw t4,20(a0) + 118: 01c52c23 sw t3,24(a0) + 11c: 00652e23 sw t1,28(a0) + 120: 03152023 sw a7,32(a0) + 124: 03052223 sw a6,36(a0) + 128: d50c sw a1,40(a0) + 12a: 02c51623 sh a2,44(a0) + 12e: 02d50723 sb a3,46(a0) + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + 132: d07e sw t6,32(sp) + 134: d27a sw t5,36(sp) + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; + 136: c100 sw s0,0(a0) + Ptr_Glob->Discr = Ident_1; + 138: 00052223 sw zero,4(a0) + Ptr_Glob->variant.var_1.Int_Comp = 40; + 13c: 01452623 sw s4,12(a0) + Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type)); + 140: 00aaa023 sw a0,0(s5) + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + 144: 00c92b03 lw s6,12(s2) + 148: 01092b83 lw s7,16(s2) + 14c: 01492c03 lw s8,20(s2) + 150: 01892c83 lw s9,24(s2) + 154: d44e sw s3,40(sp) + 156: 01c95d03 lhu s10,28(s2) + 15a: 01e94d83 lbu s11,30(s2) + + Arr_2_Glob [8][7] = 10; + 15e: 10000797 auipc a5,0x10000 + 162: faa78793 addi a5,a5,-86 # 10000108 + 166: 4429 li s0,10 + 168: 6487ae23 sw s0,1628(a5) + /* Was missing in published program. Without this statement, */ + /* Arr_2_Glob [8][7] would have an undefined value. */ + /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */ + /* overflow may occur for this array element. */ + + printf ("\n"); + 16c: 00002517 auipc a0,0x2 + 170: 6c450513 addi a0,a0,1732 # 2830 <__modsi3+0x298> + strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); + 174: d65a sw s6,44(sp) + 176: d85e sw s7,48(sp) + 178: da62 sw s8,52(sp) + 17a: dc66 sw s9,56(sp) + 17c: 03a11e23 sh s10,60(sp) + 180: 03b10f23 sb s11,62(sp) + printf ("\n"); + 184: 425010ef jal ra,1da8 <__wrap_printf> + printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n"); + 188: 00002517 auipc a0,0x2 + 18c: 46050513 addi a0,a0,1120 # 25e8 <__modsi3+0x50> + 190: 419010ef jal ra,1da8 <__wrap_printf> + printf ("\n"); + 194: 00002517 auipc a0,0x2 + 198: 69c50513 addi a0,a0,1692 # 2830 <__modsi3+0x298> + 19c: 40d010ef jal ra,1da8 <__wrap_printf> + if (Reg) + 1a0: 8181a503 lw a0,-2024(gp) # 10000028 + 1a4: 5a050963 beqz a0,756 + { + printf ("Program compiled with 'register' attribute\n"); + 1a8: 00002517 auipc a0,0x2 + 1ac: 47050513 addi a0,a0,1136 # 2618 <__modsi3+0x80> + 1b0: 3f9010ef jal ra,1da8 <__wrap_printf> + printf ("\n"); + 1b4: 00002517 auipc a0,0x2 + 1b8: 67c50513 addi a0,a0,1660 # 2830 <__modsi3+0x298> + 1bc: 3ed010ef jal ra,1da8 <__wrap_printf> + else + { + printf ("Program compiled without 'register' attribute\n"); + printf ("\n"); + } + printf ("Please give the number of runs through the benchmark: "); + 1c0: 00002517 auipc a0,0x2 + 1c4: 4b450513 addi a0,a0,1204 # 2674 <__modsi3+0xdc> + 1c8: 3e1010ef jal ra,1da8 <__wrap_printf> + { + int n; + scanf ("%d", &n); + 1cc: 008c addi a1,sp,64 + 1ce: 00002517 auipc a0,0x2 + 1d2: 4de50513 addi a0,a0,1246 # 26ac <__modsi3+0x114> + 1d6: 70a000ef jal ra,8e0 <__wrap_scanf> + Number_Of_Runs = n; + 1da: 4406 lw s0,64(sp) + } + printf ("\n"); + 1dc: 00002517 auipc a0,0x2 + 1e0: 65450513 addi a0,a0,1620 # 2830 <__modsi3+0x298> + Number_Of_Runs = n; + 1e4: c622 sw s0,12(sp) + printf ("\n"); + 1e6: 3c3010ef jal ra,1da8 <__wrap_printf> + + printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs); + 1ea: 85a2 mv a1,s0 + 1ec: 00002517 auipc a0,0x2 + 1f0: 4c450513 addi a0,a0,1220 # 26b0 <__modsi3+0x118> + 1f4: 3b5010ef jal ra,1da8 <__wrap_printf> +#ifdef TIMES + times (&time_info); + Begin_Time = (long) time_info.tms_utime; +#endif +#ifdef TIME + Begin_Time = time ( (long *) 0); + 1f8: 4501 li a0,0 + 1fa: 6da000ef jal ra,8d4