This commit is contained in:
Gabriel Konecny 2024-04-30 08:46:13 +02:00
commit 4cc156e0d0
16 changed files with 67 additions and 388 deletions

View File

@ -14,6 +14,6 @@ add_custom_target(fw-dhrystone ALL
USES_TERMINAL
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(fw-coremark ALL
COMMAND make -C ${riscvfw_SOURCE_DIR}/benchmarks/coremark/cm PORT_DIR=../tgc BOARD=${BOARD} ISA=${ISA}
COMMAND make -C ${riscvfw_SOURCE_DIR}/benchmarks/coremark BOARD=${BOARD} ISA=${ISA}
USES_TERMINAL
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

4
Jenkinsfile vendored
View File

@ -47,13 +47,13 @@ pipeline {
stage('make TGC5L') {steps { make_hello("TGC5L")}}
stage('make rtl') {steps { make_hello("rtl")}}
stage('make ehrenberg') {steps { make_hello("ehrenberg")}}
stage('make tgc-vp') {steps { make_hello("tgc-vp")}}*/
stage('make tgc_vp') {steps { make_hello("tgc_vp")}}*/
stage('make hello-world') {
matrix {
axes {
axis{
name 'BOARD'
values 'iss', 'hifive1', 'TGC5L', 'ehrenberg', 'rtl', 'tgc-vp'
values 'iss', 'hifive1', 'TGCP', 'ehrenberg', 'rtl', 'tgc_vp'
}
}
stages {

View File

@ -1,2 +1,3 @@
# Firmware
Using `make clean && bear -- make ` will cause a correct compile_commands.json to be emitted. This allows using completion tools like clangd.

@ -1 +1 @@
Subproject commit 1d55083a554450075164af01810361dd37338930
Subproject commit 87dc0ec2304adcb94a25b397a357aadae1304867

View File

@ -1,3 +1,4 @@
*.o
*.elf
*.log
*.log
/coremark.*

View File

@ -0,0 +1,33 @@
TARGET := coremark
ISA?=imc
ITERATIONS?=600 # 300 for TGC
ASM_SRCS :=
C_SRCS := core_list_join.c core_main.c core_matrix.c core_state.c core_util.c core_portme.c ee_printf.c
HEADERS := cm/coremark.h
vpath %.c cm
BOARD?=iss
LINK_TARGET=link
RISCV_ARCH:=rv32$(ISA)
ifeq ($(ISA),e)
RISCV_ABI:=ilp32e
else
RISCV_ABI:=ilp32
endif
PORT_CFLAGS = -DPERFORMANCE_RUN=1 -DCLOCKS_PER_SEC=10000000 -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
PORT_CFLAGS+= -g -O3 -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
CFLAGS = $(PORT_CFLAGS) -I. -Icm -DFLAGS_STR=\"$(FLAGS_STR)\"
CFLAGS += -DITERATIONS=$(ITERATIONS)
LDFLAGS := -g -Wl,--wrap=scanf -Wl,--wrap=printf -Wl,--wrap=exit -lgcc -lm
TOOL_DIR=$(dir $(compiler))
BSP_BASE = ../../bare-metal-bsp
include $(BSP_BASE)/env/common-gcc.mk

View File

@ -186,6 +186,7 @@ portable_init(core_portable *p, int *argc, char *argv[])
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
}
p->portable_id = 1;
ee_printf("portable_init finished.\n");
}
/* Function : portable_fini
Target specific final code

View File

@ -659,24 +659,28 @@ ee_vsprintf(char *buf, const char *fmt, va_list args)
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))
#include <platform.h>
void
uart_send_char(char c)
{
while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ;
UART0_REG(UART_REG_TXFIFO) = (unsigned char)c;
#if defined(BOARD_ehrenberg)
while (get_uart_rx_tx_reg_tx_free(uart)==0) ;
uart_write(uart, c);
if (c == '\n') {
while (get_uart_rx_tx_reg_tx_free(uart)==0) ;
uart_write(uart, '\r');
}
#elif defined(BOARD_iss)
*((uint32_t*) 0xFFFF0000) = c;
#else
while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ;
UART0_REG(UART_REG_TXFIFO) = c;
if (c == '\n') {
while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ;
UART0_REG(UART_REG_TXFIFO) = '\r';
}
#endif
}
int

View File

@ -1,94 +0,0 @@
# 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)_zicsr_zifencei
RISCV_ABI:=ilp32
TRIPLET?=riscv64-unknown-elf
# 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 = $(TRIPLET)-gcc
# Flag : LD
# Use this flag to define compiler to use
LD = $(TRIPLET)-gcc
# Flag : AS
# Use this flag to define compiler to use
AS = $(TRIPLET)-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 = -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI)
#--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

View File

@ -1,241 +0,0 @@
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_*) }
}

View File

@ -1,11 +1,12 @@
TARGET := dhrystone
ISA?=imc
ITERATIONS?=50000 # 20000 for TGC
ASM_SRCS :=
C_SRCS := dhry_stubs.c dhry_printf.c dhry_1.c dhry_2.c
C_SRCS := dhry_stubs.c dhry_1.c dhry_2.c
HEADERS := dhry.h
BOARD=iss
BOARD?=iss
LINK_TARGET=link
RISCV_ARCH:=rv32$(ISA)
ifeq ($(ISA),e)
@ -14,7 +15,7 @@ else
RISCV_ABI:=ilp32
endif
# '-lgcc -lm' are needed to add softfloat routines
CFLAGS := -g -march=$(RISCV_ARCH)_zicsr_zifencei -mabi=$(RISCV_ABI) -mcmodel=medlow -O3 -DHZ=32768 -DTIME -DNO_INIT -fno-inline -fno-builtin-printf -fno-common -Wno-implicit \
CFLAGS := -g -march=$(RISCV_ARCH)_zicsr_zifencei -mabi=$(RISCV_ABI) -mcmodel=medlow -O3 -DITERATIONS=$(ITERATIONS) -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)_zicsr_zifencei -mabi=$(RISCV_ABI) -mcmodel=medlow -Wl,--wrap=scanf -Wl,--wrap=printf -Wl,--wrap=exit -lgcc -lm

View File

@ -1,15 +0,0 @@
/* The functions in this file are only meant to support Dhrystone on an
* embedded RV32 system and are obviously incorrect in general. */
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
//#undef putchar
//int putchar(int ch)
//{
// return write(1, &ch, 1) == 1 ? ch : -1;
//}

View File

@ -1,4 +1,7 @@
#include "platform.h"
#ifndef ITERATIONS
#define ITERATIONS 20000
#endif
/* The functions in this file are only meant to support Dhrystone on an
* embedded RV32 system and are obviously incorrect in general. */
@ -11,7 +14,7 @@ long time(void)
// set the number of dhrystone iterations
void __wrap_scanf(const char* fmt, int* n)
{
*n = 200000;
*n = ITERATIONS;
}
extern volatile uint32_t tohost;

View File

@ -1,15 +0,0 @@
#include "platform.h"
/* The functions in this file are only meant to support Dhrystone on an
* embedded RV32 system and are obviously incorrect in general. */
long time(void)
{
return get_timer_value() / get_timer_freq();
}
// set the number of dhrystone iterations
void __wrap_scanf(const char* fmt, int* n)
{
*n = 100000000;
}