Skip to content
Snippets Groups Projects
Commit 6afb5790 authored by sjthales's avatar sjthales
Browse files

modification student contest

parents
No related branches found
No related tags found
No related merge requests found
// Copyright (c) 2020 Thales.
//
// Copyright and related rights are 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
// https://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Sebastien Jacq - sjthales on github.com
//
// Additional contributions by:
//
//
// file Name: CVA6 FPGA configurtion
// Project Name: CVA6 softcore
// Language: C header
//
// Description: File which defines the FPGA platform, i.e base address for each
// peripheral and others information relating to FPAG platform.
//
// =========================================================================== #
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq Created
// =========================================================================== #
#ifndef __FPGA_PLATFORM_CONFIG_H
#define __FPGA_PLATFORM_CONFIG_H
/***************************************************************************//**
* Platform frequency
*/
#define FPGA_UART_0_FREQUENCY 50000000
/***************************************************************************//**
* Peripheral base address
*/
#define FPGA_UART_0_BASE 0x10000000
#endif /* FPGA_PLATFORM_CONFIG */
/* Copyright (c) 2020 Thales.
Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copyright (C) 2019 ETH Zürich and University of Bologna
Copyright (C) 2020 OpenHW Group
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
/* This linker script is adapted from the default linker script for upstream
RISC-V GCC. It has been modified for use in verification of CORE-V cores.
*/
// Additional contributions by:
// Sebastien Jacq - sjthales on github.com
//
// Description: linkerscript for the CV32A6 platform
//
// =========================================================================== //
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq modification of the Test for CV32A6 softcore
// =========================================================================== //
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
"elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(_start)
/* CORE-V */
MEMORY
{
/* Our testbench is a bit weird in that we initialize the RAM (thus
allowing initialized sections to be placed there). Infact we dump all
sections to ram. */
ram (rwxai) : ORIGIN = 0x80000000, LENGTH = 0x40000
dbg (rwxai) : ORIGIN = 0x1A110800, LENGTH = 0x1000
}
SECTIONS
{
/* CORE-V Debugger Code: This section address must be the same as the
DM_HaltAddress parameter in the RTL */
.debugger (ORIGIN(dbg)):
{
KEEP(*(.debugger));
} >dbg
.debugger_exception (0x1A111000):
{
KEEP(*(.debugger_exception));
} >dbg
/* Debugger Stack*/
.debugger_stack : ALIGN(16)
{
PROVIDE(__debugger_stack_start = .);
. = 0x80;
} >dbg
/* CORE-V: we want a fixed entry point */
PROVIDE(__boot_address = 0x80000080);
/* CORE-V: interrupt vectors */
.vectors (ORIGIN(ram)):
{
PROVIDE(__vector_start = .);
KEEP(*(.vectors));
} >ram
/* CORE-V: crt0 init code */
.init (__boot_address):
{
KEEP (*(SORT_NONE(.init)))
KEEP (*(.text.start))
} >ram
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x10000)); . = SEGMENT_START("text-segment", 0x10000) + SIZEOF_HEADERS;
.interp : { *(.interp) } >ram
.note.gnu.build-id : { *(.note.gnu.build-id) } >ram
.hash : { *(.hash) } >ram
.gnu.hash : { *(.gnu.hash) } >ram
.dynsym : { *(.dynsym) } >ram
.dynstr : { *(.dynstr) } >ram
.gnu.version : { *(.gnu.version) } >ram
.gnu.version_d : { *(.gnu.version_d) } >ram
.gnu.version_r : { *(.gnu.version_r) } >ram
.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 = .);
} >ram
.rela.plt :
{
*(.rela.plt)
} >ram
.plt : { *(.plt) }
.iplt : { *(.iplt) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
} >ram
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >ram
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >ram
.rodata1 : { *(.rodata1) } >ram
.sdata2 :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
} >ram
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } >ram
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) } >ram
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) } >ram
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) } >ram
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } >ram
/* 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.*) } >ram
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) } >ram
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } >ram
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) } >ram
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
} >ram
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >ram
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >ram
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >ram
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >ram
.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))
} >ram
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >ram
.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)
} >ram
.data1 : { *(.data1) } >ram
.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.*)
} >ram
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.sbss :
{
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
} >ram
.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);
} >ram
. = 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 (.);
/* Heap grows upward towards end of ram */
.heap : ALIGN(16)
{
PROVIDE(__heap_start = .);
/* If end of ram is not 16-byte aligned, align to previous 16-byte
boundary */
PROVIDE(__heap_end = ALIGN(ORIGIN(ram) + LENGTH(ram) - __heap_start - 15, 16));
. = __heap_end;
} >ram
/* Stack grows downward from end of ram */
.stack (__heap_start) : ALIGN(16) /* this is a requirement of the ABI(?) */
{
PROVIDE(__stack_start = __heap_start);
. = __heap_end;
PROVIDE(__stack_end = .);
} >ram
/* 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_*) }
}
/* Copyright (c) 2017 SiFive Inc. All rights reserved.
* Copyright (c) 2019 ETH Zürich and University of Bologna
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the FreeBSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses.
*/
/* Make sure the vector table gets linked into the binary. */
.global vector_table
/* Entry point for bare metal programs */
.section .text.start
.global _start
.type _start, @function
_start:
/* initialize global pointer */
.option push
.option norelax
1: auipc gp, %pcrel_hi(__global_pointer$)
addi gp, gp, %pcrel_lo(1b)
.option pop
/* initialize stack pointer */
la sp, __stack_end
/* set vector table address */
la a0, __vector_start
ori a0, a0, 1 /*vector mode = vectored */
csrw mtvec, a0
/* clear the bss segment */
la a0, _edata
la a2, _end
sub a2, a2, a0
li a1, 0
call memset
/* new-style constructors and destructors */
la a0, __libc_fini_array
call atexit
call __libc_init_array
/* call main */
// lw a0, 0(sp) /* a0 = argc */
// addi a1, sp, __SIZEOF_POINTER__ /* a1 = argv */
// li a2, 0 /* a2 = envp = NULL */
// Initialize these variables to 0. Cannot use argc or argv
// since the stack is not initialized
li a0, 0
li a1, 0
li a2, 0
call main
tail exit
.size _start, .-_start
.global _init
.type _init, @function
.global _fini
.type _fini, @function
_init:
_fini:
/* These don't have to do anything since we use init_array/fini_array. Prevent
missing symbol error */
ret
.size _init, .-_init
.size _fini, .-_fini
#ifndef RISCV_CSR_ENCODING_H
#define RISCV_CSR_ENCODING_H
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
#define MSTATUS_HIE 0x00000004
#define MSTATUS_MIE 0x00000008
#define MSTATUS_UPIE 0x00000010
#define MSTATUS_SPIE 0x00000020
#define MSTATUS_HPIE 0x00000040
#define MSTATUS_MPIE 0x00000080
#define MSTATUS_SPP 0x00000100
#define MSTATUS_HPP 0x00000600
#define MSTATUS_MPP 0x00001800
#define MSTATUS_FS 0x00006000
#define MSTATUS_XS 0x00018000
#define MSTATUS_MPRV 0x00020000
#define MSTATUS_SUM 0x00040000
#define MSTATUS_MXR 0x00080000
#define MSTATUS_TVM 0x00100000
#define MSTATUS_TW 0x00200000
#define MSTATUS_TSR 0x00400000
#define MSTATUS32_SD 0x80000000
#define MSTATUS64_SD 0x8000000000000000
#define MCAUSE32_CAUSE 0x7FFFFFFF
#define MCAUSE64_CAUSE 0x7FFFFFFFFFFFFFFF
#define MCAUSE32_INT 0x80000000
#define MCAUSE64_INT 0x8000000000000000
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
#define SSTATUS_SPIE 0x00000020
#define SSTATUS_SPP 0x00000100
#define SSTATUS_FS 0x00006000
#define SSTATUS_XS 0x00018000
#define SSTATUS_SUM 0x00040000
#define SSTATUS_MXR 0x00080000
#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000
#define DCSR_XDEBUGVER (3U<<30)
#define DCSR_NDRESET (1<<29)
#define DCSR_FULLRESET (1<<28)
#define DCSR_EBREAKM (1<<15)
#define DCSR_EBREAKH (1<<14)
#define DCSR_EBREAKS (1<<13)
#define DCSR_EBREAKU (1<<12)
#define DCSR_STOPCYCLE (1<<10)
#define DCSR_STOPTIME (1<<9)
#define DCSR_CAUSE (7<<6)
#define DCSR_DEBUGINT (1<<5)
#define DCSR_HALT (1<<3)
#define DCSR_STEP (1<<2)
#define DCSR_PRV (3<<0)
#define DCSR_CAUSE_NONE 0
#define DCSR_CAUSE_SWBP 1
#define DCSR_CAUSE_HWBP 2
#define DCSR_CAUSE_DEBUGINT 3
#define DCSR_CAUSE_STEP 4
#define DCSR_CAUSE_HALT 5
#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
#define MCONTROL_SELECT (1U<<19)
#define MCONTROL_TIMING (1U<<18)
#define MCONTROL_ACTION (0x3fU<<12)
#define MCONTROL_CHAIN (1U<<11)
#define MCONTROL_MATCH (0xfU<<7)
#define MCONTROL_M (1U<<6)
#define MCONTROL_H (1U<<5)
#define MCONTROL_S (1U<<4)
#define MCONTROL_U (1U<<3)
#define MCONTROL_EXECUTE (1U<<2)
#define MCONTROL_STORE (1U<<1)
#define MCONTROL_LOAD (1U<<0)
#define MCONTROL_TYPE_NONE 0
#define MCONTROL_TYPE_MATCH 2
#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
#define MCONTROL_ACTION_DEBUG_MODE 1
#define MCONTROL_ACTION_TRACE_START 2
#define MCONTROL_ACTION_TRACE_STOP 3
#define MCONTROL_ACTION_TRACE_EMIT 4
#define MCONTROL_MATCH_EQUAL 0
#define MCONTROL_MATCH_NAPOT 1
#define MCONTROL_MATCH_GE 2
#define MCONTROL_MATCH_LT 3
#define MCONTROL_MATCH_MASK_LOW 4
#define MCONTROL_MATCH_MASK_HIGH 5
#define MIP_SSIP (1U << IRQ_S_SOFT)
#define MIP_HSIP (1U << IRQ_H_SOFT)
#define MIP_MSIP (1U << IRQ_M_SOFT)
#define MIP_STIP (1U << IRQ_S_TIMER)
#define MIP_HTIP (1U << IRQ_H_TIMER)
#define MIP_MTIP (1U << IRQ_M_TIMER)
#define MIP_SEIP (1U << IRQ_S_EXT)
#define MIP_HEIP (1U << IRQ_H_EXT)
#define MIP_MEIP (1U << IRQ_M_EXT)
#define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP
#define PRV_U 0
#define PRV_S 1
#define PRV_H 2
#define PRV_M 3
#define SPTBR32_MODE 0x80000000
#define SPTBR32_ASID 0x7FC00000
#define SPTBR32_PPN 0x003FFFFF
#define SPTBR64_MODE 0xF000000000000000
#define SPTBR64_ASID 0x0FFFF00000000000
#define SPTBR64_PPN 0x00000FFFFFFFFFFF
#define SPTBR_MODE_OFF 0
#define SPTBR_MODE_SV32 1
#define SPTBR_MODE_SV39 8
#define SPTBR_MODE_SV48 9
#define SPTBR_MODE_SV57 10
#define SPTBR_MODE_SV64 11
#define PMP_R 0x01
#define PMP_W 0x02
#define PMP_X 0x04
#define PMP_A 0x18
#define PMP_L 0x80
#define PMP_SHIFT 2
#define PMP_TOR 0x08
#define PMP_NA4 0x10
#define PMP_NAPOT 0x18
#define IRQ_S_SOFT 1
#define IRQ_H_SOFT 2
#define IRQ_M_SOFT 3
#define IRQ_S_TIMER 5
#define IRQ_H_TIMER 6
#define IRQ_M_TIMER 7
#define IRQ_S_EXT 9
#define IRQ_H_EXT 10
#define IRQ_M_EXT 11
#define IRQ_COP 12
#define IRQ_HOST 13
#define DEFAULT_RSTVEC 0x00001000
#define CLINT_BASE 0x02000000
#define CLINT_SIZE 0x000c0000
#define EXT_IO_BASE 0x40000000
#define DRAM_BASE 0x80000000
// page table entry (PTE) fields
#define PTE_V 0x001 // Valid
#define PTE_R 0x002 // Read
#define PTE_W 0x004 // Write
#define PTE_X 0x008 // Execute
#define PTE_U 0x010 // User
#define PTE_G 0x020 // Global
#define PTE_A 0x040 // Accessed
#define PTE_D 0x080 // Dirty
#define PTE_SOFT 0x300 // Reserved for Software
#define PTE_PPN_SHIFT 10
#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
#ifdef __riscv
#if __riscv_xlen == 64
# define MSTATUS_SD MSTATUS64_SD
# define SSTATUS_SD SSTATUS64_SD
# define RISCV_PGLEVEL_BITS 9
# define SPTBR_MODE SPTBR64_MODE
# define MCAUSE_INT MCAUSE64_INT //ML added- should we be using later encoding.h?
# define MCAUSE_CAUSE MCAUSE64_CAUSE //ML added- should we be using later encoding.h?
#else
# define MSTATUS_SD MSTATUS32_SD
# define SSTATUS_SD SSTATUS32_SD
# define RISCV_PGLEVEL_BITS 10
# define SPTBR_MODE SPTBR32_MODE
# define MCAUSE_INT MCAUSE32_INT //ML added- should we be using later encoding.h?
# define MCAUSE_CAUSE MCAUSE32_CAUSE //ML added- should we be using later encoding.h?
#endif
#define RISCV_PGSHIFT 12
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
#ifndef __ASSEMBLER__
#ifdef __GNUC__
#define read_reg(reg) ({ unsigned long __tmp; \
asm volatile ("mv %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) ({ \
asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
#define swap_csr(reg, val) ({ unsigned long __tmp; \
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
__tmp; })
#define set_csr(reg, bit) ({ unsigned long __tmp; \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
__tmp; })
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
__tmp; })
#if 0
#define csr_write(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
asm volatile ("csrw " __ASM_STR(csr) ", %0" \
: : "rK" (__v) \
: "memory"); \
})
#define csr_write(csr, val) \
({ \
unsigned long __v = (unsigned long)(val); \
__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
: : "rK" (__v) \
: "memory"); \
})
#endif
#define rdtime() read_csr(time)
#define rdcycle() read_csr(cycle)
#define rdinstret() read_csr(instret)
#endif //__GNUC__
#endif //__ASSEMBLER__
#endif //__riscv
#endif // RISCV_CSR_ENCODING_H
#ifndef HAL_ASSERT_HEADER
#define HAL_ASSERT_HEADER
/***************************************************************************//**
* ASSERT() implementation.
******************************************************************************/
/* Disable assertions if we do not recognize the compiler. */
#define ASSERT(CHECK)
#define HAL_ASSERT(CHECK)
#endif /* HAL_ASSERT_HEADER */
/*
* Copyright 2019 ETH Zürich and University of Bologna
*
* 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.
*/
/* Exception codes */
#define EXCEPTION_ILLEGAL_INSN 2
#define EXCEPTION_BREAKPOINT 3
#define EXCEPTION_ECALL_M 11
.section .text.handlers
.global __no_irq_handler
.global sw_irq_handler
.global verification_irq_handler
/* exception handling */
__no_irq_handler:
la a0, no_exception_handler_msg
jal ra, puts
j __no_irq_handler
sw_irq_handler:
/* While we are still using puts in handlers, save all caller saved
regs. Eventually, some of these saves could be deferred. */
addi sp,sp,-64
sw ra, 0(sp)
sw a0, 4(sp)
sw a1, 8(sp)
sw a2, 12(sp)
sw a3, 16(sp)
sw a4, 20(sp)
sw a5, 24(sp)
sw a6, 28(sp)
sw a7, 32(sp)
sw t0, 36(sp)
sw t1, 40(sp)
sw t2, 44(sp)
sw t3, 48(sp)
sw t4, 52(sp)
sw t5, 56(sp)
sw t6, 60(sp)
csrr t0, mcause
li t1, EXCEPTION_ILLEGAL_INSN
beq t0, t1, handle_illegal_insn
li t1, EXCEPTION_ECALL_M
beq t0, t1, handle_ecall
li t1, EXCEPTION_BREAKPOINT
beq t0, t1, handle_ebreak
j handle_unknown
handle_ecall:
jal ra, handle_syscall
j end_handler_incr_mepc
handle_ebreak:
/* TODO support debug handling requirements. */
la a0, ebreak_msg
jal ra, puts
j end_handler_incr_mepc
handle_illegal_insn:
la a0, illegal_insn_msg
jal ra, puts
j end_handler_incr_mepc
handle_unknown:
la a0, unknown_msg
jal ra, puts
/* We don't know what interrupt/exception is being handled, so don't
increment mepc. */
j end_handler_ret
end_handler_incr_mepc:
csrr t0, mepc
lb t1, 0(t0)
li a0, 0x3
and t1, t1, a0
/* Increment mepc by 2 or 4 depending on whether the instruction at mepc
is compressed or not. */
bne t1, a0, end_handler_incr_mepc2
addi t0, t0, 2
end_handler_incr_mepc2:
addi t0, t0, 2
csrw mepc, t0
end_handler_ret:
lw ra, 0(sp)
lw a0, 4(sp)
lw a1, 8(sp)
lw a2, 12(sp)
lw a3, 16(sp)
lw a4, 20(sp)
lw a5, 24(sp)
lw a6, 28(sp)
lw a7, 32(sp)
lw t0, 36(sp)
lw t1, 40(sp)
lw t2, 44(sp)
lw t3, 48(sp)
lw t4, 52(sp)
lw t5, 56(sp)
lw t6, 60(sp)
addi sp,sp,64
mret
/* this interrupt can be generated for verification purposes, random or when the
PC is equal to a given value*/
verification_irq_handler:
mret
.section .rodata
illegal_insn_msg:
.string "illegal instruction exception handler entered\n"
ecall_msg:
.string "ecall exception handler entered\n"
ebreak_msg:
.string "ebreak exception handler entered\n"
unknown_msg:
.string "unknown exception handler entered\n"
no_exception_handler_msg:
.string "no exception handler installed\n"
/*******************************************************************************
* Copyright (c) 2020 Thales.
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
* MPFS HAL Embedded Software
*
*/
/*******************************************************************************
*
* @author Microchip-FPGA Embedded Systems Solutions
*
* Definitions and functions associated with PLIC interrupts.
*/
// Additional contributions by:
// Sebastien Jacq - sjthales on github.com
//
// Description: Definitions and functions associated with PLIC interrupts
// for the CVA6 platform
//
// =========================================================================== //
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq modification of the Test for CVA6 softcore
// =========================================================================== //
#ifndef MSS_PLIC_H
#define MSS_PLIC_H
#include <stdint.h>
#include "encoding.h"
#include "hal_assert.h"
/*
*Return value from External IRQ handler. This will be used to disable the
*Return External interrupt.
*/
#define EXT_IRQ_KEEP_ENABLED 0U
#define EXT_IRQ_DISABLE 1U
/***************************************************************************//**
* PLIC source Interrupt numbers:
*/
typedef enum
{
NoInterrupt_IRQHandler = 0,
UART_0_PLIC_IRQHandler = 1,
QSPI_0_PLIC_IRQHandler = 2,
ETH_0_PLIC_IRQHandler = 3,
External_4_IRQHandler = 4,
External_5_IRQHandler = 5,
External_6_IRQHandler = 6,
External_7_IRQHandler = 7,
External_8_IRQHandler = 8,
External_9_IRQHandler = 9,
External_10_IRQHandler = 10,
External_11_IRQHandler = 11,
External_12_IRQHandler = 12,
External_13_IRQHandler = 13,
External_14_IRQHandler = 14,
External_15_IRQHandler = 15,
External_16_IRQHandler = 16,
External_17_IRQHandler = 17,
External_18_IRQHandler = 18,
External_19_IRQHandler = 19,
External_20_IRQHandler = 20,
External_21_IRQHandler = 21,
External_22_IRQHandler = 22,
External_23_IRQHandler = 23,
External_24_IRQHandler = 24,
External_25_IRQHandler = 25,
External_26_IRQHandler = 26,
External_27_IRQHandler = 27,
External_28_IRQHandler = 28,
External_29_IRQHandler = 29,
External_30_IRQHandler = 30
} PLIC_IRQn_Type;
#define MAX_PLIC_INT External_30_IRQHandler
typedef struct
{
volatile uint32_t PRIORITY_THRESHOLD;
volatile uint32_t CLAIM_COMPLETE;
volatile uint32_t reserved[(0x1000/4)-2];
} IRQ_Target_Type;
typedef struct
{
volatile uint32_t ENABLES[31U];
} Target_Enables_Type;
#define PLIC_SET_UP_REGISTERS 2U
#define PLIC_NUM_SOURCES 30U
#define PLIC_NUM_PRIORITIES 7U
#define NUM_CLAIM_REGS 2U
typedef struct
{
volatile uint32_t RESERVED0;
/*-------------------- Source Priority --------------------*/
volatile uint32_t SOURCE_PRIORITY[PLIC_NUM_SOURCES];
volatile uint32_t RESERVED1[(0x1000/4) - (PLIC_NUM_SOURCES + 1)];
/*-------------------- Pending array --------------------*/
volatile const uint32_t PENDING_ARRAY[PLIC_SET_UP_REGISTERS];
volatile uint32_t RESERVED2[(0x1000/4) - PLIC_SET_UP_REGISTERS];
/*-------------------- Target enables --------------------*/
//volatile Target_Enables_Type TARGET_ENABLES[PLIC_SET_UP_REGISTERS];
//volatile uint32_t RESERVED3[(0x200000-0x2000) - PLIC_SET_UP_REGISTERS];
/*-----------------Target Mode Enables--------------------*/
volatile uint32_t HART0_MMODE_ENA[PLIC_SET_UP_REGISTERS];
volatile uint32_t RESERVED3a[(0x80/4) - PLIC_SET_UP_REGISTERS];
volatile uint32_t HART0_SMODE_ENA[PLIC_SET_UP_REGISTERS];
volatile uint32_t RESERVED3[(0x80/4) - PLIC_SET_UP_REGISTERS];
volatile uint32_t RESERVED4[(0x200000-0x2000)/4 - PLIC_SET_UP_REGISTERS];
/*--- Target Priority threshold and claim/complete---------*/
IRQ_Target_Type TARGET[NUM_CLAIM_REGS];
} PLIC_Type;
#define TARGET_OFFSET_HART0_M 0U
#define TARGET_OFFSET_HART0_S 1U
/***************************************************************************//**
* PLIC: Platform Level Interrupt Controller
*/
#define PLIC_BASE_ADDR 0x0C000000UL
#define PLIC ((PLIC_Type *)PLIC_BASE_ADDR)
/*-------------------------------------------------------------------------*//**
* The function PLIC_init() initializes the PLIC controller and enables the
* global external interrupt bit.
*/
/*-----------------Hart Mode Enables--------------------*/
static inline void PLIC_init(void)
{
uint32_t inc;
uint64_t hart_id = read_csr(mhartid);
/* Disable all interrupts for the current hart. */
for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
{
PLIC->HART0_MMODE_ENA[inc] = 0U;
PLIC->HART0_SMODE_ENA[inc] = 0U;
}
PLIC->TARGET[TARGET_OFFSET_HART0_M].PRIORITY_THRESHOLD = 0U;
/* Disable supervisor level */
PLIC->TARGET[TARGET_OFFSET_HART0_S].PRIORITY_THRESHOLD = 7U;
/* Enable machine external interrupts. */
set_csr(mie, MIP_MEIP);
}
/***************************************************************************//**
* The function PLIC_EnableIRQ() enables the external interrupt for the
* interrupt number indicated by the parameter IRQn.
*/
static inline void PLIC_EnableIRQ(PLIC_IRQn_Type IRQn)
{
uint64_t hart_id = read_csr(mhartid);
uint32_t current;
switch(hart_id)
{
case 0:
current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
current |= (uint32_t)1 << (IRQn % 32U);
PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
break;
default:
break;
}
}
/***************************************************************************//**
* The function PLIC_DisableIRQ() disables the external interrupt for the
* interrupt number indicated by the parameter IRQn.
* NOTE:
* This function can be used to disable the external interrupt from outside
* external interrupt handler function.
* This function MUST NOT be used from within the External Interrupt
* handler.
* If you wish to disable the external interrupt while the interrupt handler
* for that external interrupt is executing then you must use the return
* value EXT_IRQ_DISABLE to return from the extern interrupt handler.
*/
static inline void PLIC_DisableIRQ(PLIC_IRQn_Type IRQn)
{
uint32_t current;
uint64_t hart_id = read_csr(mhartid);
switch(hart_id)
{
case 0:
current = PLIC->HART0_MMODE_ENA[IRQn / 32U];
current &= ~((uint32_t)1 << (IRQn % 32U));
PLIC->HART0_MMODE_ENA[IRQn / 32U] = current;
break;
default:
break;
}
}
/***************************************************************************//**
* The function PLIC_SetPriority() sets the priority for the external interrupt
* for the interrupt number indicated by the parameter IRQn.
*/
static inline void PLIC_SetPriority(PLIC_IRQn_Type IRQn, uint32_t priority)
{
if((IRQn > NoInterrupt_IRQHandler) && (IRQn < PLIC_NUM_SOURCES))
{
PLIC->SOURCE_PRIORITY[IRQn-1] = priority;
}
}
/***************************************************************************//**
* The function PLIC_GetPriority() returns the priority for the external
* interrupt for the interrupt number indicated by the parameter IRQn.
*/
static inline uint32_t PLIC_GetPriority(PLIC_IRQn_Type IRQn)
{
uint32_t ret_val = 0U;
if((IRQn > NoInterrupt_IRQHandler) && (IRQn < PLIC_NUM_SOURCES))
{
ret_val = PLIC->SOURCE_PRIORITY[IRQn-1];
}
return(ret_val);
}
/*static inline uint32_t PLIC_pending(PLIC_IRQn_Type IRQn)
{
return (PLIC->PENDING_ARRAY[IRQn/32U] & (0x01U<<(IRQn%32U)));
}*/
/***************************************************************************//**
* The function PLIC_ClaimIRQ() claims the interrupt from the PLIC controller.
*/
static inline uint32_t PLIC_ClaimIRQ(void)
{
unsigned long hart_id = read_csr(mhartid);
return PLIC->TARGET[hart_id].CLAIM_COMPLETE;
}
/***************************************************************************//**
* The function PLIC_CompleteIRQ() indicates to the PLIC controller the
* interrupt is processed and claim is complete.
*/
static inline void PLIC_CompleteIRQ(uint32_t source)
{
unsigned long hart_id = read_csr(mhartid);
PLIC->TARGET[hart_id].CLAIM_COMPLETE = source;
}
/***************************************************************************//**
*
* The function PLIC_SetPriority_Threshold() sets the threshold for a particular
* hart. The default threshold on reset is 0.
* The PFSoC Core Complex supports setting of an interrupt priority threshold
* via the threshold register. The threshold is a WARL field, where the PFSoC
* Core Complex supports a maximum threshold of 7.
* The PFSoC Core Complex will mask all PLIC interrupts of a priority less than
* or equal to threshold. For example, a threshold value of zero permits all
* interrupts with non-zero priority, whereas a value of 7 masks all
* interrupts.
*/
static inline void PLIC_SetPriority_Threshold(uint32_t threshold)
{
uint64_t hart_id = read_csr(mhartid);
//const unsigned long lookup[5U] = {0U, 1U, 3U, 5U, 7U};
//ASSERT(threshold <= 7);
PLIC->TARGET[hart_id].PRIORITY_THRESHOLD = threshold;
}
/***************************************************************************//**
* PLIC_ClearPendingIRQ(void)
* This is only called by the startup hart and only once
* Clears any pending interrupts as PLIC can be in unknown state on startup
*/
static inline void PLIC_ClearPendingIRQ(void)
{
volatile uint32_t int_num = PLIC_ClaimIRQ();
volatile int32_t wait_possible_int;
while ( int_num != NoInterrupt_IRQHandler)
{
uint8_t disable = EXT_IRQ_KEEP_ENABLED;
PLIC_CompleteIRQ(int_num);
wait_possible_int = 0xFU;
while (wait_possible_int)
{
wait_possible_int--;
}
int_num = PLIC_ClaimIRQ(); /* obtain interrupt, auto clears */
}
}
/***************************************************************************//**
* This function is only called from one hart on startup
*/
static inline void PLIC_init_on_reset(void)
{
uint32_t inc;
/* default all priorities so effectively disabled */
for(inc = 0U; inc < PLIC_NUM_SOURCES; ++inc)
{
/* priority must be greater than threshold to be enabled, so setting to
* 7 disables */
PLIC->SOURCE_PRIORITY[inc] = 0U;
}
for(inc = 0U; inc < NUM_CLAIM_REGS; ++inc)
{
PLIC->TARGET[inc].PRIORITY_THRESHOLD = 7U;
}
/* and clear all the enables */
for(inc = 0UL; inc < PLIC_SET_UP_REGISTERS; inc++)
{
PLIC->HART0_MMODE_ENA[inc] = 0U;
PLIC->HART0_SMODE_ENA[inc] = 0U;
}
/* clear any pending interrupts- in case already there */
PLIC_ClearPendingIRQ();
}
#endif /* MSS_PLIC_H */
/*******************************************************************************
* Copyright (c) 2020 Thales.
* Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
*
* SPDX-License-Identifier: MIT
*
* MPFS HAL Embedded Software
*
*/
/*******************************************************************************
*
* @author Microchip-FPGA Embedded Systems Solutions
* @brief MPFS MSS Interrupt Function stubs.
*
*/
// Additional contributions by:
// Sebastien Jacq - sjthales on github.com
//
// Description: The functions below will only be linked with the application
// code if the user does not provide an implementation for these
// functions. These functions are defined with weak linking so that
// they can be overridden by a function with same prototype in the
// user's application code.
//
// =========================================================================== //
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq modification of the Test for CVA6 softcore
// =========================================================================== //
#include <unistd.h>
__attribute__((weak)) uint8_t NoInterrupt_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t UART_0_PLIC_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t QSPI_0_PLIC_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t ETH_0_PLIC_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_4_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_5_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_6_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_7_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_8_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_9_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_10_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_11_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_12_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_13_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_14_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_15_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_16_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_17_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_18_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_19_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_20_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_21_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_22_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_23_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_24_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_25_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_26_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_27_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_28_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_29_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_30_IRQHandler(void)
{
return(0);
}
__attribute__((weak)) uint8_t External_31_IRQHandler(void)
{
return(0);
}
/* An extremely minimalist syscalls.c for newlib
* Based on riscv newlib libgloss/riscv/sys_*.c
*
* Copyright (c) 2020 Thales.
* Copyright 2019 Clifford Wolf
* Copyright 2019 ETH Zürich and University of Bologna
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// Additional contributions by:
// Sebastien Jacq - sjthales on github.com
//
// =========================================================================== //
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq modification of the Test for CVA6 softcore
// =========================================================================== //
#include <sys/stat.h>
#include <sys/timeb.h>
#include <sys/times.h>
#include <sys/utime.h>
#include <newlib.h>
#include <unistd.h>
#include <errno.h>
#include <machine/syscall.h>
#include <assert.h>
#undef errno
extern int errno;
/* write to this reg for outputting strings */
#define STDOUT_REG 0x10000000
/* write test result of program to this reg */
#define RESULT_REG 0x20000000
/* write exit value of program to this reg */
#define EXIT_REG 0x80040000
#define STDOUT_FILENO 1
/* It turns out that older newlib versions use different symbol names which goes
* against newlib recommendations. Anyway this is fixed in later version.
*/
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
#define _sbrk sbrk
#define _write write
#define _close close
#define _lseek lseek
#define _read read
#define _fstat fstat
#define _isatty isatty
#endif
/************************************************************************************/
/********************** STDIO_THRU_UART ********************************/
/************************************************************************************/
#ifdef STDIO_THRU_UART
#include "uart.h"
#ifndef STDIO_BAUD_RATE
#define STDIO_BAUD_RATE UART_115200_BAUD
#endif
static uart_instance_t * const gp_my_uart = &g_uart_0;
/*------------------------------------------------------------------------------
* Global flag used to indicate if the UART driver needs to be initialized.
*/
static int g_stdio_uart_init_done = 0;
#endif /* STDIO_THRU_UART */
/***********************************************************************************/
/********************** END STDIO_THRU_UART ********************************/
/************************************************************************************/
/* Upstream newlib now defines this in libgloss/riscv/internal_syscall.h. */
long
__syscall_error(long a0)
{
errno = -a0;
return -1;
}
void unimplemented_syscall()
{
const char *p = "Unimplemented system call called!\n";
while (*p)
*(volatile int *)STDOUT_REG = *(p++);
}
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
{
errno = ENOSYS;
return -1;
}
int _access(const char *file, int mode)
{
errno = ENOSYS;
return -1;
}
int _chdir(const char *path)
{
errno = ENOSYS;
return -1;
}
int _chmod(const char *path, mode_t mode)
{
errno = ENOSYS;
return -1;
}
int _chown(const char *path, uid_t owner, gid_t group)
{
errno = ENOSYS;
return -1;
}
int _close(int file)
{
return -1;
}
int _execve(const char *name, char *const argv[], char *const env[])
{
errno = ENOMEM;
return -1;
}
void _exit(int exit_status)
{
*(volatile int *)EXIT_REG = exit_status;
asm volatile("wfi");
/* _exit should not return */
while (1) {};
}
int _faccessat(int dirfd, const char *file, int mode, int flags)
{
errno = ENOSYS;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _fstat(int file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
// errno = -ENOSYS;
// return -1;
}
int _fstatat(int dirfd, const char *file, struct stat *st, int flags)
{
errno = ENOSYS;
return -1;
}
int _ftime(struct timeb *tp)
{
errno = ENOSYS;
return -1;
}
char *_getcwd(char *buf, size_t size)
{
errno = -ENOSYS;
return NULL;
}
int _getpid()
{
return 1;
}
int _gettimeofday(struct timeval *tp, void *tzp)
{
errno = -ENOSYS;
return -1;
}
int _isatty(int file)
{
return (file == STDOUT_FILENO);
}
int _kill(int pid, int sig)
{
errno = EINVAL;
return -1;
}
int _link(const char *old_name, const char *new_name)
{
errno = EMLINK;
return -1;
}
off_t _lseek(int file, off_t ptr, int dir)
{
return 0;
}
int _lstat(const char *file, struct stat *st)
{
errno = ENOSYS;
return -1;
}
int _open(const char *name, int flags, int mode)
{
return -1;
}
int _openat(int dirfd, const char *name, int flags, int mode)
{
errno = ENOSYS;
return -1;
}
ssize_t _read(int file, void *ptr, size_t len)
{
return 0;
}
int _stat(const char *file, struct stat *st)
{
st->st_mode = S_IFCHR;
return 0;
// errno = ENOSYS;
// return -1;
}
long _sysconf(int name)
{
return -1;
}
clock_t _times(struct tms *buf)
{
return -1;
}
int _unlink(const char *name)
{
errno = ENOENT;
return -1;
}
int _utime(const char *path, const struct utimbuf *times)
{
errno = ENOSYS;
return -1;
}
int _wait(int *status)
{
errno = ECHILD;
return -1;
}
ssize_t _write(int file, const void *ptr, size_t len)
{
#ifdef STDIO_THRU_UART
/*--------------------------------------------------------------------------
* Initialize the UART driver if it is the first time this function is
* called.
*/
if(!g_stdio_uart_init_done)
{
UART_init(gp_my_uart,
STDIO_BAUD_RATE,
UART_DATA_8_BITS | UART_NO_PARITY | UART_ONE_STOP_BIT);
g_stdio_uart_init_done = 1;
}
/*--------------------------------------------------------------------------
* Output text to the UART.
*/
UART_polled_tx(gp_my_uart, (uint8_t *)ptr, len);
return len;
#else /* STDIO_THRU_UART */
const char *cptr = (char *)ptr;
if (file != STDOUT_FILENO)
{
errno = ENOSYS;
return -1;
}
const void *eptr = cptr + len;
while (cptr != eptr)
*(volatile int *)STDOUT_REG = *cptr++;
return len;
#endif /* STDIO_THRU_UART */
}
extern char __heap_start[];
extern char __heap_end[];
static char *brk = __heap_start;
int _brk(void *addr)
{
brk = addr;
return 0;
}
void *_sbrk(ptrdiff_t incr)
{
char *old_brk = brk;
register long sp asm("sp");
char *new_brk = brk += incr;
if (new_brk < (char *) sp && new_brk < __heap_end)
{
brk = new_brk;
return old_brk;
}
else
{
errno = ENOMEM;
return (void *) -1;
}
}
void handle_syscall (long a0,
long a1,
long a2,
long a3,
__attribute__((unused)) long a4,
__attribute__((unused)) long a5,
__attribute__((unused)) long a6,
long a7) {
#ifdef __riscv_32e
register long syscall_id asm("t0");
#else
long syscall_id = a7;
#endif
switch (syscall_id) {
case SYS_exit:
_exit (a0);
break;
case SYS_read:
_read (a0, (void *) a1, a2);
break;
case SYS_write:
_write (a0, (const void *) a1, a2);
break;
case SYS_getpid:
_getpid ();
break;
case SYS_kill:
_kill (a0, a1);
break;
case SYS_open:
_open ((const char *) a0, a1, a2);
break;
case SYS_openat:
_openat (a0, (const char *) a1, a2, a3);
break;
case SYS_close:
_close (a0);
break;
case SYS_lseek:
_lseek (a0, a1, a2);
break;
case SYS_brk:
_brk ((void *) a0);
break;
case SYS_link:
_link ((const char *) a0, (const char *) a1);
break;
case SYS_unlink:
_unlink ((const char *) a0);
break;
case SYS_chdir:
_chdir ((const char *) a0);
break;
case SYS_getcwd:
_getcwd ((char *) a0, a1);
break;
case SYS_stat:
_stat ((const char *) a0, (struct stat *) a1);
break;
case SYS_fstat:
_fstat (a0, (struct stat *) a1);
break;
case SYS_lstat:
_lstat ((const char *) a0, (struct stat *) a1);
break;
case SYS_fstatat:
_fstatat (a0, (const char *) a1, (struct stat *) a2, a3);
break;
case SYS_access:
_access ((const char *) a0, a1);
break;
case SYS_faccessat:
_faccessat (a0, (const char *) a1, a2, a3);
break;
case SYS_gettimeofday:
_gettimeofday ((struct timeval *) a0, (void *) a1);
break;
case SYS_times:
_times ((struct tms *) a0);
break;
default:
unimplemented_syscall ();
break;
}
}
/*
* Copyright (c) 2020 Thales.
* Copyright 2019 ETH Zürich and University of Bologna
*
* 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.
*/
// Additional contributions by:
// Sebastien Jacq - sjthales on github.com
//
// Description: interrupt vector table
//
// =========================================================================== //
// Revisions :
// Date Version Author Description
// 2020-10-06 0.1 S.Jacq modification of the Test for CVA6 softcore
// =========================================================================== //
.section .vectors, "ax"
.option norvc
.global vector_table
vector_table:
j sw_irq_handler
j UART_0_PLIC_IRQHandler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j __no_irq_handler
j verification_irq_handler
#!/usr/bin/env python
# Copyright (c) 2020 Thales.
#
# Copyright and related rights are 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
# https://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law
# or agreed to in writing, software, hardware and materials distributed under
# this 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.
#
# Author: Sebastien Jacq - sjthales on github.com
#
# Additional contributions by:
#
#
# script Name: bin2mem
# Project Name: CVA6 softcore
# Language: Python
#
# Description: Script to generate mem data file for simulation from binary
# application file.
#
# =========================================================================== #
# Revisions :
# Date Version Author Description
# 2020-10-06 0.1 S.Jacq Created
# =========================================================================== #
import sys
import math
import binascii
###############################################################################
# Start of file
###############################################################################
if(len(sys.argv) < 2):
print "Usage bin2mem.py FILENAME"
quit()
filename = sys.argv[1].strip('.bin') + ".mem"
mem_file = open(filename, 'wb')
with open(sys.argv[1], "rb") as f:
bytes_read = f.read(8)
while bytes_read:
bytes_read_inv = bytes_read[::-1]
mem_file.write("%s\n" %binascii.hexlify(bytes_read_inv) )
bytes_read = f.read(8)
###############################################################################
# close all files
###############################################################################
mem_file.close()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment