Fixed target adapter to properly handle register reading

This commit is contained in:
Eyck Jentzsch 2017-09-25 20:38:40 +02:00
parent 4ce4b2562b
commit 710d61e304
8 changed files with 99 additions and 45 deletions

View File

@ -17,8 +17,8 @@ include(cmake/Submodules.cmake)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(warnings "-Wall -Wextra -Werror") set(warnings "-Wall -Wextra -Werror")
set(CMAKE_CXX_FLAG_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAG_RELEASE "-O3 -DNDEBUG")
set(CMAKE_C_FLAG_RELEASE "-O2 -DNDEBUG") set(CMAKE_C_FLAG_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAG_DEBUG "-Og") set(CMAKE_CXX_FLAG_DEBUG "-Og")
set(CMAKE_C_FLAG_DEBUG "-Og") set(CMAKE_C_FLAG_DEBUG "-Og")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
@ -26,6 +26,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
endif() endif()
FIND_PACKAGE(Threads) FIND_PACKAGE(Threads)
FIND_PACKAGE(Tcmalloc)
set(PROJECT_3PARTY_DIRS external sr_report sr_signal) set(PROJECT_3PARTY_DIRS external sr_report sr_signal)
include(sc-components/cmake/clang-format.cmake) include(sc-components/cmake/clang-format.cmake)

38
cmake/FindTcmalloc.cmake Normal file
View File

@ -0,0 +1,38 @@
# - Find Tcmalloc
# Find the native Tcmalloc library
#
# Tcmalloc_LIBRARIES - List of libraries when using Tcmalloc.
# Tcmalloc_FOUND - True if Tcmalloc found.
if (USE_TCMALLOC)
set(Tcmalloc_NAMES tcmalloc)
else ()
set(Tcmalloc_NAMES tcmalloc_minimal tcmalloc)
endif ()
find_library(Tcmalloc_LIBRARY NO_DEFAULT_PATH
NAMES ${Tcmalloc_NAMES}
PATHS ${HT_DEPENDENCY_LIB_DIR} /lib /usr/lib /usr/local/lib /opt/local/lib
)
if (Tcmalloc_LIBRARY)
set(Tcmalloc_FOUND TRUE)
set( Tcmalloc_LIBRARIES ${Tcmalloc_LIBRARY} )
else ()
set(Tcmalloc_FOUND FALSE)
set( Tcmalloc_LIBRARIES )
endif ()
if (Tcmalloc_FOUND)
message(STATUS "Found Tcmalloc: ${Tcmalloc_LIBRARY}")
else ()
message(STATUS "Not Found Tcmalloc: ${Tcmalloc_LIBRARY}")
if (Tcmalloc_FIND_REQUIRED)
message(STATUS "Looked for Tcmalloc libraries named ${Tcmalloc_NAMES}.")
message(FATAL_ERROR "Could NOT find Tcmalloc library")
endif ()
endif ()
mark_as_advanced(
Tcmalloc_LIBRARY
)

@ -1 +1 @@
Subproject commit f8b842549e961d88cd7122c9d210ebe198283c85 Subproject commit 743e314de55023df0942c5de146c109a0b8b1513

View File

@ -44,6 +44,9 @@ if(SCV_FOUND)
target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES}) target_link_libraries (${APPLICATION_NAME} ${SCV_LIBRARIES})
endif() endif()
target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} ) target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} )
if (Tcmalloc_FOUND)
target_link_libraries(${APPLICATION_NAME} ${Tcmalloc_LIBRARIES})
endif(Tcmalloc_FOUND)
# Says how and where to install software # Says how and where to install software
# Targets: # Targets:

View File

@ -36,6 +36,9 @@ target_link_libraries(${APPLICATION_NAME} sc-components)
target_link_libraries(${APPLICATION_NAME} external) target_link_libraries(${APPLICATION_NAME} external)
target_link_libraries(${APPLICATION_NAME} ${llvm_libs}) target_link_libraries(${APPLICATION_NAME} ${llvm_libs})
target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} ) target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} )
if (Tcmalloc_FOUND)
target_link_libraries(${APPLICATION_NAME} ${Tcmalloc_LIBRARIES})
endif(Tcmalloc_FOUND)
# Says how and where to install software # Says how and where to install software
# Targets: # Targets:

View File

@ -485,14 +485,12 @@ status target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vec
// return idx<0?:; // return idx<0?:;
data.clear(); data.clear();
avail.clear(); avail.clear();
std::vector<uint8_t> reg_data; const uint8_t* reg_base = vm->get_arch()->get_regs_base_ptr();
for (size_t reg_no = 0; reg_no < arch::traits<ARCH>::NUM_REGS; ++reg_no) { for (size_t reg_no = 0; reg_no < arch::traits<ARCH>::NUM_REGS; ++reg_no) {
auto reg_bit_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto reg_width = reg_bit_width / 8; unsigned offset = traits<ARCH>::reg_byte_offset(reg_no);
reg_data.resize(reg_width); for (size_t j = 0; j < reg_width; ++j) {
vm->get_arch()->get_reg(reg_no, reg_data); data.push_back(*(reg_base+offset+j));
for (size_t j = 0; j < reg_data.size(); ++j) {
data.push_back(reg_data[j]);
avail.push_back(0xff); avail.push_back(0xff);
} }
} }
@ -510,15 +508,15 @@ status target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vec
} }
template <typename ARCH> status target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) { template <typename ARCH> status target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) {
size_t data_index = 0;
auto reg_count = arch::traits<ARCH>::NUM_REGS; auto reg_count = arch::traits<ARCH>::NUM_REGS;
std::vector<uint8_t> reg_data; auto* reg_base = vm->get_arch()->get_regs_base_ptr();
auto iter = data.data();
for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) {
auto reg_bit_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto reg_width = reg_bit_width / 8; auto offset = traits<ARCH>::reg_byte_offset(reg_no);
vm->get_arch()->set_reg(reg_no, std::copy(iter , iter + reg_width, reg_base);
std::vector<uint8_t>(data.begin() + data_index, data.begin() + data_index + reg_width)); iter+=4;
data_index += reg_width; reg_base+=offset;
} }
return Ok; return Ok;
} }
@ -529,9 +527,12 @@ status target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vect
if (reg_no < 65) { if (reg_no < 65) {
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename // auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
// arch::traits<ARCH>::reg_e>(reg_no))/8; // arch::traits<ARCH>::reg_e>(reg_no))/8;
data.resize(0); auto* reg_base = vm->get_arch()->get_regs_base_ptr();
vm->get_arch()->get_reg(reg_no, data); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
avail.resize(data.size()); data.resize(reg_width);
avail.resize(reg_width);
auto offset = traits<ARCH>::reg_byte_offset(reg_no);
std::copy(reg_base+offset, reg_base+offset+reg_width, data.begin());
std::fill(avail.begin(), avail.end(), 0xff); std::fill(avail.begin(), avail.end(), 0xff);
} else { } else {
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65); typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65);
@ -545,9 +546,12 @@ status target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vect
template <typename ARCH> template <typename ARCH>
status target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) { status target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) {
if (reg_no < 65) if (reg_no < 65){
vm->get_arch()->set_reg(reg_no, data); auto* reg_base = vm->get_arch()->get_regs_base_ptr();
else { auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto offset = traits<ARCH>::reg_byte_offset(reg_no);
std::copy(data.begin(), data.begin() + reg_width, reg_base+offset);
} else {
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65); typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65);
vm->get_arch()->write(a, data.size(), data.data()); vm->get_arch()->write(a, data.size(), data.data());
} }

View File

@ -4094,7 +4094,8 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl
#define CREATE_FUNCS(ARCH) \ #define CREATE_FUNCS(ARCH) \
template <> std::unique_ptr<vm_if> create<ARCH>(ARCH * core, unsigned short port, bool dump) { \ template <> std::unique_ptr<vm_if> create<ARCH>(ARCH * core, unsigned short port, bool dump) { \
std::unique_ptr<rv32imac::vm_impl<ARCH>> ret = std::make_unique<rv32imac::vm_impl<ARCH>>(*core, dump); \ std::unique_ptr<rv32imac::vm_impl<ARCH>> ret = \
std::make_unique<rv32imac::vm_impl<ARCH>>(*core, dump); \
debugger::server<debugger::gdb_session>::run_server(ret.get(), port); \ debugger::server<debugger::gdb_session>::run_server(ret.get(), port); \
return ret; \ return ret; \
} \ } \
@ -4157,14 +4158,12 @@ status target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vec
// return idx<0?:; // return idx<0?:;
data.clear(); data.clear();
avail.clear(); avail.clear();
std::vector<uint8_t> reg_data; const uint8_t* reg_base = vm->get_arch()->get_regs_base_ptr();
for (size_t reg_no = 0; reg_no < arch::traits<ARCH>::NUM_REGS; ++reg_no) { for (size_t reg_no = 0; reg_no < arch::traits<ARCH>::NUM_REGS; ++reg_no) {
auto reg_bit_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto reg_width = reg_bit_width / 8; unsigned offset = traits<ARCH>::reg_byte_offset(reg_no);
reg_data.resize(reg_width); for (size_t j = 0; j < reg_width; ++j) {
vm->get_arch()->get_reg(reg_no, reg_data); data.push_back(*(reg_base+offset+j));
for (size_t j = 0; j < reg_data.size(); ++j) {
data.push_back(reg_data[j]);
avail.push_back(0xff); avail.push_back(0xff);
} }
} }
@ -4182,15 +4181,15 @@ status target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vec
} }
template <typename ARCH> status target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) { template <typename ARCH> status target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) {
size_t data_index = 0;
auto reg_count = arch::traits<ARCH>::NUM_REGS; auto reg_count = arch::traits<ARCH>::NUM_REGS;
std::vector<uint8_t> reg_data; auto* reg_base = vm->get_arch()->get_regs_base_ptr();
auto iter = data.data();
for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) {
auto reg_bit_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto reg_width = reg_bit_width / 8; auto offset = traits<ARCH>::reg_byte_offset(reg_no);
vm->get_arch()->set_reg(reg_no, std::copy(iter , iter + reg_width, reg_base);
std::vector<uint8_t>(data.begin() + data_index, data.begin() + data_index + reg_width)); iter+=4;
data_index += reg_width; reg_base+=offset;
} }
return Ok; return Ok;
} }
@ -4201,9 +4200,12 @@ status target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vect
if (reg_no < 65) { if (reg_no < 65) {
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename // auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
// arch::traits<ARCH>::reg_e>(reg_no))/8; // arch::traits<ARCH>::reg_e>(reg_no))/8;
data.resize(0); auto* reg_base = vm->get_arch()->get_regs_base_ptr();
vm->get_arch()->get_reg(reg_no, data); auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
avail.resize(data.size()); data.resize(reg_width);
avail.resize(reg_width);
auto offset = traits<ARCH>::reg_byte_offset(reg_no);
std::copy(reg_base+offset, reg_base+offset+reg_width, data.begin());
std::fill(avail.begin(), avail.end(), 0xff); std::fill(avail.begin(), avail.end(), 0xff);
} else { } else {
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65); typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65);
@ -4217,9 +4219,12 @@ status target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vect
template <typename ARCH> template <typename ARCH>
status target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) { status target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) {
if (reg_no < 65) if (reg_no < 65){
vm->get_arch()->set_reg(reg_no, data); auto* reg_base = vm->get_arch()->get_regs_base_ptr();
else { auto reg_width = arch::traits<ARCH>::reg_bit_width(static_cast<typename arch::traits<ARCH>::reg_e>(reg_no))/8;
auto offset = traits<ARCH>::reg_byte_offset(reg_no);
std::copy(data.begin(), data.begin() + reg_width, reg_base+offset);
} else {
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65); typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65);
vm->get_arch()->write(a, data.size(), data.data()); vm->get_arch()->write(a, data.size(), data.data());
} }

@ -1 +1 @@
Subproject commit 8272a27a0ef24d8b7b596ae8dc5adeb6f422f1b2 Subproject commit c852e8228d4351ea672a2367fd36ce8965ff3347