blob: fbc614ee5757c0de52b626b984a92f27c5c6fde0 [file] [log] [blame]
/*
* fwrisc_zephyr_tests.cpp
*
* Copyright 2018 Matthew Ballance
*
* 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.
*
*
* Created on: Nov 16, 2018
* Author: ballance
*/
#include "fwrisc_zephyr_tests.h"
#include <stdio.h>
#include "CmdlineProcessor.h"
#include "ElfSymtabReader.h"
fwrisc_zephyr_tests::fwrisc_zephyr_tests() : fwrisc_ctest_base(10000000) {
m_ram_console = 0;
m_raw_console = false;
m_halt_addr = 0; // Don't halt
m_msg_listener = [&](const std::string &msg) { }; // Empty
}
fwrisc_zephyr_tests::~fwrisc_zephyr_tests() {
// TODO Auto-generated destructor stub
}
void fwrisc_zephyr_tests::SetUp() {
fwrisc_ctest_base::SetUp();
m_ram_console = m_symtab.find_sym("ram_console").st_value;
// _Fault is called when the main function returns
m_halt_addr = m_symtab.find_sym("_Fault").st_value;
filter_func("char_out");
filter_func("ram_console_out");
filter_func("__udivsi3");
filter_func("__umodsi3");
filter_func("__mulsi3");
fprintf(stdout, "Ram Console: 0x%08x\n", m_ram_console);
}
void fwrisc_zephyr_tests::regwrite(uint32_t raddr, uint32_t rdata) {
}
void fwrisc_zephyr_tests::exec(uint32_t addr, uint32_t instr) {
fwrisc_ctest_base::exec(addr, instr);
// std::string sym;
// if (m_trace_funcs) {
// if (m_symtab.find_sym(addr, sym)) {
// fprintf(stdout, "EXEC: %s (0x%08x)\n", sym.c_str(), addr);
// }
// }
// if (m_trace_instr) {
// fprintf(stdout, "EXEC: 0x%08x\n", addr);
// }
//
// if (addr == m_halt_addr) {
// fprintf(stdout, "hit halt address 0x%08x\n", m_halt_addr);
// m_end_of_test = true;
// dropObjection(this);
// }
}
void fwrisc_zephyr_tests::memwrite(uint32_t addr, uint8_t mask, uint32_t data) {
if (addr >= m_ram_console && addr < (m_ram_console+1024)) {
char ch;
switch (mask) {
case 1: ch = ((data >> 0) & 0xFF); break;
case 2: ch = ((data >> 8) & 0xFF); break;
case 4: ch = ((data >> 16) & 0xFF); break;
case 8: ch = ((data >> 24) & 0xFF); break;
}
if (ch) {
if (m_raw_console) {
fputc(ch, stdout);
fflush(stdout);
}
if (ch == '\n') {
if (!m_raw_console) {
fputs("# ", stdout);
fputs(m_buffer.c_str(), stdout);
fputs("\n", stdout);
fflush(stdout);
}
m_msg_listener(m_buffer);
m_console_out.push_back(m_buffer);
m_buffer.clear();
} else {
m_buffer.push_back(ch);
}
}
}
}
void fwrisc_zephyr_tests::check(const char *exp[], uint32_t exp_sz) {
ASSERT_EQ(m_end_of_test, true);
for (uint32_t i=0; i<exp_sz; i++) {
const char *msg = exp[i];
bool found = false;
for (std::vector<std::string>::const_iterator it=m_console_out.begin();
it!=m_console_out.end(); it++) {
std::string line = (*it);
if (line == msg) {
found = true;
break;
}
}
if (!found) {
fprintf(stdout, "Error: Failed to find msg \"%s\"\n", msg);
}
ASSERT_EQ(true, found);
}
}
TEST_F(fwrisc_zephyr_tests, dhrystone) {
const char *exp[] = {
"Hello World! fwrisc_sim"
};
m_msg_listener = [&](const std::string &msg) {
if (msg == "Hello World! fwrisc_sim") {
m_end_of_test = true;
GoogletestHdl::dropObjection();
}
};
run();
check(exp, sizeof(exp)/sizeof(const char *));
}
TEST_F(fwrisc_zephyr_tests, hello_world) {
const char *exp[] = {
"Hello World! fwrisc_sim"
};
m_msg_listener = [&](const std::string &msg) {
if (msg == "Hello World! fwrisc_sim") {
m_end_of_test = true;
GoogletestHdl::dropObjection();
}
};
run();
check(exp, sizeof(exp)/sizeof(const char *));
}
TEST_F(fwrisc_zephyr_tests, synchronization) {
int threadB_count = 0;
const char *exp[] = {
"threadA: Hello World from fwrisc_sim!",
"threadB: Hello World from fwrisc_sim!"
};
m_msg_listener = [&](const std::string &msg) {
if (msg.substr(0, strlen("threadB")) == "threadB") {
threadB_count++;
}
if (threadB_count >= 2) {
m_end_of_test = true;
GoogletestHdl::dropObjection();
}
};
run();
check(exp, sizeof(exp)/sizeof(const char *));
}
TEST_F(fwrisc_zephyr_tests, philosophers) {
const char *exp[] = {
"An implementation of a solution to the Dining Philosophers"
};
m_raw_console = true;
run();
check(exp, sizeof(exp)/sizeof(const char *));
}
TEST_F(fwrisc_zephyr_tests, ripe) {
const char *exp[] = {
"An implementation of a solution to the Dining Philosophers"
};
// m_raw_console = true;
run();
check(exp, sizeof(exp)/sizeof(const char *));
}
TEST_F(fwrisc_zephyr_tests, coretest) {
run();
ASSERT_EQ(m_end_of_test, true);
}