mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 13:17:41 -04:00
Add DPI ELF section loader
This commit is contained in:
parent
3d4128a51f
commit
1bd4848c5f
6 changed files with 369 additions and 2 deletions
2
Makefile
2
Makefile
|
@ -54,6 +54,8 @@ build: $(library) build-agents build-interfaces
|
|||
vlog${questa_version} ${compile_flag} -work ${library} -incr ${envs} ${sequences} ${test_pkg} ${list_incdir} -suppress 2583
|
||||
# Compile source files
|
||||
vlog${questa_version} ${compile_flag} -work ${library} -incr ${src} ${tbs} ${list_incdir} -suppress 2583
|
||||
# Compile top level with DPI headers
|
||||
vlog -sv tb/core_tb.sv tb/dpi/elfdpi.cc -ccflags "-g -std=c++11 " -dpiheader tb/dpi/elfdpi.h
|
||||
# Optimize top level
|
||||
vopt${questa_version} ${compile_flag} -work ${library} ${test_top_level} -o ${test_top_level}_optimized +acc -check_synthesis
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0ac80c22cac54b0f348b051d41fefaffca802d09
|
||||
Subproject commit 14f61ce4833126b1327926ad12f7d7bc653702b6
|
|
@ -9,6 +9,8 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module core_tb;
|
||||
import "DPI-C" function chandle read_elf(string fn);
|
||||
import "DPI-C" function longint unsigned get_symbol_address(string sym);
|
||||
|
||||
import uvm_pkg::*;
|
||||
import core_lib_pkg::*;
|
||||
|
@ -123,9 +125,13 @@ module core_tb;
|
|||
end
|
||||
|
||||
task preload_memories();
|
||||
longint unsigned address;
|
||||
logic [7:0] rmem [0:16384];
|
||||
|
||||
$display("Reading memory");
|
||||
void'(read_elf("/home/zarubaf/ariane/sourcecode/test/rv64ui-p-add"));
|
||||
address = get_symbol_address("tohost");
|
||||
$display("tohost: %0h\n", address);
|
||||
|
||||
$readmemh("test/rv64ui-p-add.v", rmem);
|
||||
|
||||
// copy bitwise from verilog file
|
||||
|
|
121
tb/dpi/elf.h
Normal file
121
tb/dpi/elf.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
// See LICENSE for details.
|
||||
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define IS_ELF(hdr) \
|
||||
((hdr).e_ident[0] == 0x7f && (hdr).e_ident[1] == 'E' && \
|
||||
(hdr).e_ident[2] == 'L' && (hdr).e_ident[3] == 'F')
|
||||
|
||||
#define IS_ELF32(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 1)
|
||||
#define IS_ELF64(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 2)
|
||||
|
||||
#define PT_LOAD 1
|
||||
|
||||
#define SHT_NOBITS 8
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[16];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
uint32_t e_entry;
|
||||
uint32_t e_phoff;
|
||||
uint32_t e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint32_t sh_flags;
|
||||
uint32_t sh_addr;
|
||||
uint32_t sh_offset;
|
||||
uint32_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint32_t sh_addralign;
|
||||
uint32_t sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t p_type;
|
||||
uint32_t p_offset;
|
||||
uint32_t p_vaddr;
|
||||
uint32_t p_paddr;
|
||||
uint32_t p_filesz;
|
||||
uint32_t p_memsz;
|
||||
uint32_t p_flags;
|
||||
uint32_t p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t st_name;
|
||||
uint32_t st_value;
|
||||
uint32_t st_size;
|
||||
uint8_t st_info;
|
||||
uint8_t st_other;
|
||||
uint16_t st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[16];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
uint64_t e_entry;
|
||||
uint64_t e_phoff;
|
||||
uint64_t e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint64_t sh_flags;
|
||||
uint64_t sh_addr;
|
||||
uint64_t sh_offset;
|
||||
uint64_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint64_t sh_addralign;
|
||||
uint64_t sh_entsize;
|
||||
} Elf64_Shdr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t p_type;
|
||||
uint32_t p_flags;
|
||||
uint64_t p_offset;
|
||||
uint64_t p_vaddr;
|
||||
uint64_t p_paddr;
|
||||
uint64_t p_filesz;
|
||||
uint64_t p_memsz;
|
||||
uint64_t p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t st_name;
|
||||
uint8_t st_info;
|
||||
uint8_t st_other;
|
||||
uint16_t st_shndx;
|
||||
uint64_t st_value;
|
||||
uint64_t st_size;
|
||||
} Elf64_Sym;
|
||||
|
||||
#endif
|
87
tb/dpi/elfdpi.cc
Normal file
87
tb/dpi/elfdpi.cc
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include "vpi_user.h"
|
||||
#include "elfdpi.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "elf.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
std::map<std::string, uint64_t> symbols;
|
||||
|
||||
uint64_t get_symbol_address (const char* symb) {
|
||||
return symbols[symb];
|
||||
}
|
||||
|
||||
void* read_elf(const char* fn) {
|
||||
|
||||
int fd = open(fn, O_RDONLY);
|
||||
struct stat s;
|
||||
// check thtat the file exists
|
||||
assert(fd != -1);
|
||||
|
||||
if (fstat(fd, &s) < 0)
|
||||
abort();
|
||||
size_t size = s.st_size;
|
||||
// map the file to memory
|
||||
char* buf = (char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
assert(buf != MAP_FAILED);
|
||||
close(fd);
|
||||
// check that this is an elf file
|
||||
assert(size >= sizeof(Elf64_Ehdr));
|
||||
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
|
||||
assert(IS_ELF32(*eh64) || IS_ELF64(*eh64));
|
||||
|
||||
#define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t) do { \
|
||||
ehdr_t* eh = (ehdr_t*)buf; \
|
||||
phdr_t* ph = (phdr_t*)(buf + eh->e_phoff); \
|
||||
assert(size >= eh->e_phoff + eh->e_phnum*sizeof(*ph)); \
|
||||
for (unsigned i = 0; i < eh->e_phnum; i++) { \
|
||||
if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { \
|
||||
if (ph[i].p_filesz) { \
|
||||
assert(size >= ph[i].p_offset + ph[i].p_filesz); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
shdr_t* sh = (shdr_t*)(buf + eh->e_shoff); \
|
||||
assert(size >= eh->e_shoff + eh->e_shnum*sizeof(*sh)); \
|
||||
assert(eh->e_shstrndx < eh->e_shnum); \
|
||||
assert(size >= sh[eh->e_shstrndx].sh_offset + sh[eh->e_shstrndx].sh_size); \
|
||||
char *shstrtab = buf + sh[eh->e_shstrndx].sh_offset; \
|
||||
unsigned strtabidx = 0, symtabidx = 0; \
|
||||
for (unsigned i = 0; i < eh->e_shnum; i++) { \
|
||||
unsigned max_len = sh[eh->e_shstrndx].sh_size - sh[i].sh_name; \
|
||||
assert(sh[i].sh_name < sh[eh->e_shstrndx].sh_size); \
|
||||
assert(strnlen(shstrtab + sh[i].sh_name, max_len) < max_len); \
|
||||
if (sh[i].sh_type & SHT_NOBITS) continue; \
|
||||
assert(size >= sh[i].sh_offset + sh[i].sh_size); \
|
||||
if (strcmp(shstrtab + sh[i].sh_name, ".strtab") == 0) \
|
||||
strtabidx = i; \
|
||||
if (strcmp(shstrtab + sh[i].sh_name, ".symtab") == 0) \
|
||||
symtabidx = i; \
|
||||
} \
|
||||
if (strtabidx && symtabidx) { \
|
||||
char* strtab = buf + sh[strtabidx].sh_offset; \
|
||||
sym_t* sym = (sym_t*)(buf + sh[symtabidx].sh_offset); \
|
||||
for (unsigned i = 0; i < sh[symtabidx].sh_size/sizeof(sym_t); i++) { \
|
||||
unsigned max_len = sh[strtabidx].sh_size - sym[i].st_name; \
|
||||
assert(sym[i].st_name < sh[strtabidx].sh_size); \
|
||||
assert(strnlen(strtab + sym[i].st_name, max_len) < max_len); \
|
||||
symbols[strtab + sym[i].st_name] = sym[i].st_value; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
if (IS_ELF32(*eh64))
|
||||
LOAD_ELF(Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Sym);
|
||||
else
|
||||
LOAD_ELF(Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Sym);
|
||||
|
||||
munmap(buf, size);
|
||||
|
||||
return &symbols;
|
||||
}
|
151
tb/dpi/elfdpi.h
Normal file
151
tb/dpi/elfdpi.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* MTI_DPI */
|
||||
|
||||
/*
|
||||
* Copyright 2002-2016 Mentor Graphics Corporation.
|
||||
*
|
||||
* Note:
|
||||
* This file is automatically generated.
|
||||
* Please do not edit this file - you will lose your edits.
|
||||
*
|
||||
* Settings when this file was generated:
|
||||
* PLATFORM = 'linux_x86_64'
|
||||
*/
|
||||
#ifndef INCLUDED_ELFDPI
|
||||
#define INCLUDED_ELFDPI
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define DPI_LINK_DECL extern "C"
|
||||
#else
|
||||
#define DPI_LINK_DECL
|
||||
#endif
|
||||
|
||||
#include "svdpi.h"
|
||||
|
||||
|
||||
#ifndef MTI_INCLUDED_TYPEDEF_uvm_hdl_path_slice
|
||||
#define MTI_INCLUDED_TYPEDEF_uvm_hdl_path_slice
|
||||
|
||||
typedef struct {
|
||||
const char* path;
|
||||
int offset;
|
||||
int size;
|
||||
} uvm_hdl_path_slice;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MTI_INCLUDED_TYPEDEF_uvm_printer_row_info
|
||||
#define MTI_INCLUDED_TYPEDEF_uvm_printer_row_info
|
||||
|
||||
typedef struct {
|
||||
int level;
|
||||
const char* name;
|
||||
const char* type_name;
|
||||
const char* size;
|
||||
const char* val;
|
||||
} uvm_printer_row_info;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef MTI_INCLUDED_TYPEDEF_uvm_reg_bus_op
|
||||
#define MTI_INCLUDED_TYPEDEF_uvm_reg_bus_op
|
||||
|
||||
typedef struct {
|
||||
int kind;
|
||||
svBitVecVal addr[SV_PACKED_DATA_NELEMS(64)];
|
||||
svBitVecVal data[SV_PACKED_DATA_NELEMS(64)];
|
||||
int n_bits;
|
||||
svBitVecVal byte_en[SV_PACKED_DATA_NELEMS(8)];
|
||||
int status;
|
||||
} uvm_reg_bus_op;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
uint64_t
|
||||
get_symbol_address(
|
||||
const char* sym);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
void*
|
||||
read_elf(
|
||||
const char* fn);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
const char*
|
||||
uvm_dpi_get_next_arg_c();
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
const char*
|
||||
uvm_dpi_get_tool_name_c();
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
const char*
|
||||
uvm_dpi_get_tool_version_c();
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
void*
|
||||
uvm_dpi_regcomp(
|
||||
const char* regex);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_dpi_regexec(
|
||||
void* preg,
|
||||
const char* str);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
void
|
||||
uvm_dpi_regfree(
|
||||
void* preg);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
void
|
||||
uvm_dump_re_cache();
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
const char*
|
||||
uvm_glob_to_re(
|
||||
const char* glob);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_check_path(
|
||||
const char* path);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_deposit(
|
||||
const char* path,
|
||||
const svLogicVecVal* value);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_force(
|
||||
const char* path,
|
||||
const svLogicVecVal* value);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_read(
|
||||
const char* path,
|
||||
svLogicVecVal* value);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_release(
|
||||
const char* path);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_hdl_release_and_read(
|
||||
const char* path,
|
||||
svLogicVecVal* value);
|
||||
|
||||
DPI_LINK_DECL DPI_DLLESPEC
|
||||
int
|
||||
uvm_re_match(
|
||||
const char* re,
|
||||
const char* str);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue