diff --git a/cpp/hal/data_sample_raspberry.h b/cpp/hal/data_sample_raspberry.h index a0b5e1e7..f1296e0f 100644 --- a/cpp/hal/data_sample_raspberry.h +++ b/cpp/hal/data_sample_raspberry.h @@ -100,6 +100,9 @@ class DataSample_Raspberry final : public DataSample DataSample_Raspberry(const uint32_t in_data, const uint64_t in_timestamp) : DataSample{in_timestamp}, data{in_data} { } + DataSample_Raspberry(const uint32_t in_data) : DataSample{0}, data{in_data} + { + } DataSample_Raspberry() = default; ~DataSample_Raspberry() override = default; diff --git a/cpp/hal/gpiobus_virtual.cpp b/cpp/hal/gpiobus_virtual.cpp index abcf39bd..101b178e 100644 --- a/cpp/hal/gpiobus_virtual.cpp +++ b/cpp/hal/gpiobus_virtual.cpp @@ -32,31 +32,23 @@ bool GPIOBUS_Virtual::Init(mode_e mode) GPIO_FUNCTION_TRACE GPIOBUS::Init(mode); + LOGTRACE("%s Setting up shared memory", __PRETTY_FUNCTION__) signals = make_unique(SHARED_MEM_NAME); + if(!signals->is_valid()){ + LOGWARN("Unable to setup shared memory. Do you have scsisim running? Are you running as root?") + }else + { + LOGINFO("Successfully mapped shared memory") + } + return true; } void GPIOBUS_Virtual::Cleanup() { - // Set control signals - PinSetSignal(PIN_ENB, OFF); - PinSetSignal(PIN_ACT, OFF); - PinSetSignal(PIN_TAD, OFF); - PinSetSignal(PIN_IND, OFF); - PinSetSignal(PIN_DTD, OFF); - PinConfig(PIN_ACT, GPIO_INPUT); - PinConfig(PIN_TAD, GPIO_INPUT); - PinConfig(PIN_IND, GPIO_INPUT); - PinConfig(PIN_DTD, GPIO_INPUT); + LOGTRACE("%s", __PRETTY_FUNCTION__) - // Initialize all signals - for (int i = 0; SignalTable[i] >= 0; i++) { - int pin = SignalTable[i]; - PinSetSignal(pin, OFF); - PinConfig(pin, GPIO_INPUT); - PullConfig(pin, GPIO_PULLNONE); - } } void GPIOBUS_Virtual::Reset() diff --git a/cpp/scsidump/scsidump_core.cpp b/cpp/scsidump/scsidump_core.cpp index 0e1475ff..febbdf59 100644 --- a/cpp/scsidump/scsidump_core.cpp +++ b/cpp/scsidump/scsidump_core.cpp @@ -38,7 +38,9 @@ using namespace piscsi_util; void ScsiDump::CleanUp() { + LOGTRACE("%s", __PRETTY_FUNCTION__) if (bus != nullptr) { + LOGTRACE("%s trying bus cleanup", __PRETTY_FUNCTION__) bus->Cleanup(); } } @@ -198,6 +200,7 @@ void ScsiDump::Command(scsi_command cmd, vector& cdb) const void ScsiDump::DataIn(int length) { + LOGTRACE("%s length: %d", __PRETTY_FUNCTION__, length) WaitPhase(phase_t::datain); if (!bus->ReceiveHandShake(buffer.data(), length)) { @@ -207,6 +210,8 @@ void ScsiDump::DataIn(int length) void ScsiDump::DataOut(int length) { + LOGTRACE("%s length: %d", __PRETTY_FUNCTION__, length) + WaitPhase(phase_t::dataout); if (!bus->SendHandShake(buffer.data(), length, BUS::SEND_NO_DELAY)) { @@ -216,6 +221,8 @@ void ScsiDump::DataOut(int length) void ScsiDump::Status() const { + LOGTRACE("%s", __PRETTY_FUNCTION__) + WaitPhase(phase_t::status); if (array buf; bus->ReceiveHandShake(buf.data(), 1) != 1) { @@ -225,6 +232,8 @@ void ScsiDump::Status() const void ScsiDump::MessageIn() const { + LOGTRACE("%s", __PRETTY_FUNCTION__) + WaitPhase(phase_t::msgin); if (array buf; bus->ReceiveHandShake(buf.data(), 1) != 1) { @@ -239,6 +248,8 @@ void ScsiDump::BusFree() const void ScsiDump::TestUnitReady() const { + LOGTRACE("%s", __PRETTY_FUNCTION__) + vector cdb(6); Command(scsi_command::eCmdTestUnitReady, cdb); @@ -251,6 +262,8 @@ void ScsiDump::TestUnitReady() const void ScsiDump::RequestSense() { + LOGTRACE("%s", __PRETTY_FUNCTION__) + vector cdb(6); cdb[4] = 0xff; Command(scsi_command::eCmdRequestSense, cdb); @@ -282,6 +295,8 @@ void ScsiDump::Inquiry() pair ScsiDump::ReadCapacity() { + LOGTRACE("%s", __PRETTY_FUNCTION__) + vector cdb(10); Command(scsi_command::eCmdReadCapacity10, cdb); @@ -330,6 +345,8 @@ pair ScsiDump::ReadCapacity() void ScsiDump::Read10(uint32_t bstart, uint32_t blength, uint32_t length) { + LOGTRACE("%s start:%d blen:%d len:%d", __PRETTY_FUNCTION__, bstart, blength, length) + vector cdb(10); cdb[2] = (uint8_t)(bstart >> 24); cdb[3] = (uint8_t)(bstart >> 16); @@ -350,6 +367,8 @@ void ScsiDump::Read10(uint32_t bstart, uint32_t blength, uint32_t length) void ScsiDump::Write10(uint32_t bstart, uint32_t blength, uint32_t length) { + LOGTRACE("%s start:%d blen:%d len:%d", __PRETTY_FUNCTION__, bstart, blength, length) + vector cdb(10); cdb[2] = (uint8_t)(bstart >> 24); cdb[3] = (uint8_t)(bstart >> 16); @@ -370,6 +389,7 @@ void ScsiDump::Write10(uint32_t bstart, uint32_t blength, uint32_t length) void ScsiDump::WaitForBusy() const { + LOGTRACE("%s", __PRETTY_FUNCTION__) // Wait for busy for up to 2 s int count = 10000; do { @@ -404,18 +424,18 @@ int ScsiDump::run(const vector& args) try { ParseArguments(args); -// #ifndef USE_SEL_EVENT_ENABLE -// cerr << "Error: No PiSCSI hardware support" << endl; -// return EXIT_FAILURE; -// #endif + // #ifndef USE_SEL_EVENT_ENABLE + // cerr << "Error: No PiSCSI hardware support" << endl; + // return EXIT_FAILURE; + // #endif return DumpRestore(); } catch (const parser_exception& e) { cerr << "Error: " << e.what() << endl; - CleanUp(); + // CleanUp(); - return EXIT_FAILURE; + // return EXIT_FAILURE; } CleanUp(); @@ -425,6 +445,8 @@ int ScsiDump::run(const vector& args) int ScsiDump::DumpRestore() { + LOGTRACE("%s", __PRETTY_FUNCTION__) + const auto inq_info = GetDeviceInfo(); fstream fs; @@ -524,6 +546,7 @@ int ScsiDump::DumpRestore() ScsiDump::inquiry_info_t ScsiDump::GetDeviceInfo() { + LOGTRACE("%s", __PRETTY_FUNCTION__) // Assert RST for 1 ms bus->SetRST(true); const timespec ts = {.tv_sec = 0, .tv_nsec = 1000 * 1000}; diff --git a/cpp/scsisim/scsisim_core.cpp b/cpp/scsisim/scsisim_core.cpp index 8e613148..91ae0794 100644 --- a/cpp/scsisim/scsisim_core.cpp +++ b/cpp/scsisim/scsisim_core.cpp @@ -11,6 +11,7 @@ #include "shared/log.h" #include "shared/piscsi_util.h" #include "spdlog/sinks/stdout_color_sinks.h" +#include "hal/data_sample_raspberry.h" #include "scsisim_defs.h" #include @@ -97,12 +98,14 @@ bool ScsiSim::ParseArgument(const vector& args) opterr = 1; int opt; - while ((opt = getopt(static_cast(args.size()), args.data(), "-L:")) != -1) { + while ((opt = getopt(static_cast(args.size()), args.data(), "-L:t")) != -1) { switch (opt) { case 'L': log_level = optarg; continue; - + case 't': + test_mode = true; + break; default: return false; } @@ -141,6 +144,13 @@ int ScsiSim::run(const vector& args) return -1; } + // We just want to run the test client. After we're done, we can + // return. + if(test_mode){ + TestClient(); + return EXIT_SUCCESS; + } + // Signal handler to detach all devices on a KILL or TERM signal struct sigaction termination_handler; termination_handler.sa_handler = TerminationHandler; @@ -149,26 +159,30 @@ int ScsiSim::run(const vector& args) sigaction(SIGINT, &termination_handler, nullptr); sigaction(SIGTERM, &termination_handler, nullptr); - signals = make_unique(SHARED_MEM_NAME); + signals = make_unique(SHARED_MEM_NAME, true); - uint32_t prev_value = -1; + uint32_t prev_value = signals->get(); int dot_counter = 0; while (running) { if (enable_debug) { uint32_t new_value = signals->get(); + + PrintDifferences(DataSample_Raspberry(new_value), DataSample_Raspberry(prev_value)); + // Note, this won't necessarily print ever data change. It will // just give an indication of activity if (new_value != prev_value) { LOGTRACE("%s Value changed to %08X", __PRETTY_FUNCTION__, new_value); - prev_value = new_value; } + prev_value = new_value; + if(++dot_counter > 1000){ printf("."); dot_counter = 0; - } + } } usleep(1000); } - return 0; + return EXIT_SUCCESS; } diff --git a/cpp/scsisim/scsisim_core.h b/cpp/scsisim/scsisim_core.h index 70e8f307..416b4086 100644 --- a/cpp/scsisim/scsisim_core.h +++ b/cpp/scsisim/scsisim_core.h @@ -13,6 +13,7 @@ #include #include "shared/shared_memory.h" +#include "hal/data_sample.h" using namespace std; @@ -33,9 +34,16 @@ class ScsiSim int InitSharedMemory(); void TeardownSharedMemory(); + void PrintDifferences(const DataSample ¤t, const DataSample &previous); + void TestClient(); + bool enable_debug = false; unique_ptr signals; + uint32_t prev_data; + bool running; + + bool test_mode = false; }; diff --git a/cpp/scsisim/scsisim_debug.cpp b/cpp/scsisim/scsisim_debug.cpp new file mode 100644 index 00000000..b24159f6 --- /dev/null +++ b/cpp/scsisim/scsisim_debug.cpp @@ -0,0 +1,100 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator PiSCSI for Raspberry Pi +// +// Copyright (C) 2023 akuker +// +// [ SCSI Bus Emulator ] +// +//--------------------------------------------------------------------------- +#include "scsisim_core.h" +#include "shared/log.h" +#include "shared/piscsi_util.h" +#include "spdlog/sinks/stdout_color_sinks.h" +#include "hal/gpiobus_factory.h" + +#include "hal/data_sample.h" +#include "scsisim_defs.h" +#include +#include +#include +#include +#include + +void ScsiSim::PrintDifferences(const DataSample& current, const DataSample& previous) +{ + if (current.GetRawCapture() != previous.GetRawCapture()) { + stringstream s; + s << "Data changed: <"; + + // << setfill('0') << setw(2) << hex << GetBuffer()[0]; + // logger.Trace(s.str()); + + if (current.GetDAT() != previous.GetDAT()) { + s << "DAT(" << setw(2) << hex << (int)current.GetDAT() << ") "; + } + if (current.GetBSY() != previous.GetBSY()) { + s << "BSY(" << current.GetBSY() << ") "; + } + if (current.GetSEL() != previous.GetSEL()) { + s << "SEL(" << current.GetSEL() << ") "; + } + if (current.GetATN() != previous.GetATN()) { + s << "ATN(" << current.GetATN() << ") "; + } + if (current.GetACK() != previous.GetACK()) { + s << "ACK(" << current.GetACK() << ") "; + } + if (current.GetRST() != previous.GetRST()) { + s << "RST(" << current.GetRST() << ") "; + } + if (current.GetMSG() != previous.GetMSG()) { + s << "MSG(" << current.GetMSG() << ") "; + }; + if (current.GetCD() != previous.GetCD()) { + s << "CD(" << current.GetCD() << ") "; + } + if (current.GetIO() != previous.GetIO()) { + s << "IO(" << current.GetIO() << ") "; + } + if (current.GetREQ() != previous.GetREQ()) { + s << "REQ(" << current.GetREQ() << ") "; + } + if (current.GetACT() != previous.GetACT()) { + s << "ACT(" << current.GetACT() << ") "; + } + s << ">" << flush; + + LOGTRACE("%s", s.str().c_str()); + } +} + +void ScsiSim::TestClient(){ + + LOGINFO("TESTING!!!") + int sleep_time = 10000; + + unique_ptr bus = GPIOBUS_Factory::Create(BUS::mode_e::INITIATOR); + + LOGINFO("bus->SetBSY"); bus->SetBSY(1); usleep(sleep_time); bus->SetBSY(0); usleep(sleep_time); + LOGINFO("bus->SetSEL"); bus->SetSEL(1); usleep(sleep_time); bus->SetSEL(0); usleep(sleep_time); + LOGINFO("bus->SetATN"); bus->SetATN(1); usleep(sleep_time); bus->SetATN(0); usleep(sleep_time); + LOGINFO("bus->SetACK"); bus->SetACK(1); usleep(sleep_time); bus->SetACK(0); usleep(sleep_time); + LOGINFO("bus->SetRST"); bus->SetRST(1); usleep(sleep_time); bus->SetRST(0); usleep(sleep_time); + LOGINFO("bus->SetMSG"); bus->SetMSG(1); usleep(sleep_time); bus->SetMSG(0); usleep(sleep_time); + LOGINFO("bus->SetCD"); bus->SetCD(1); usleep(sleep_time); bus->SetCD(0); usleep(sleep_time); + LOGINFO("bus->SetIO"); bus->SetIO(1); usleep(sleep_time); bus->SetIO(0); usleep(sleep_time); + LOGINFO("bus->SetREQ"); bus->SetREQ(1); usleep(sleep_time); bus->SetREQ(0); usleep(sleep_time); + LOGINFO("bus->SetACT"); bus->SetACT(1); usleep(sleep_time); bus->SetACT(0); usleep(sleep_time); + for(uint32_t i = 0; i <= 0xFF; i++){ + LOGINFO("bus->SetDAT(%02X)", i); bus->SetDAT((uint8_t)i); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time); + } + // LOGINFO("bus->SetDAT(0x01)"); bus->SetDAT(1); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time); + // LOGINFO("bus->SetDAT(0xFF)"); bus->SetDAT(1); usleep(sleep_time); bus->SetDAT(0); usleep(sleep_time); + + if (bus != nullptr) { + LOGTRACE("%s trying bus cleanup", __PRETTY_FUNCTION__) + bus->Cleanup(); + } + +} \ No newline at end of file diff --git a/cpp/shared/shared_memory.cpp b/cpp/shared/shared_memory.cpp index c949658c..700e092f 100644 --- a/cpp/shared/shared_memory.cpp +++ b/cpp/shared/shared_memory.cpp @@ -10,12 +10,17 @@ #include #include -SharedMemory::SharedMemory(std::string region_name) : m_valid(true), m_name(region_name) +SharedMemory::SharedMemory(std::string region_name, bool is_primary) + : m_valid(true), m_primary(is_primary), m_name(region_name) { LOGINFO("%s Opening shared memory %s", __PRETTY_FUNCTION__, region_name.c_str()) // Get shared memory - int mode = S_IRWXU | S_IRWXG; - if ((m_fd_shared_mem = shm_open(region_name.c_str(), O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) { + int mode = S_IRWXU | S_IRWXG; + int oflag = O_RDWR | O_TRUNC; + if (is_primary) { + oflag |= O_CREAT; + } + if ((m_fd_shared_mem = shm_open(region_name.c_str(), oflag, mode)) == -1) { LOGERROR("Unable to open shared memory %s. Is scsisim already running?", region_name.c_str()); m_valid = false; return; @@ -42,21 +47,20 @@ SharedMemory::SharedMemory(std::string region_name) : m_valid(true), m_name(regi LOGINFO("%s Shared memory region successfully memory mapped", __PRETTY_FUNCTION__) } +// Note: The normal logging functions can not be used here. The logger objects +// may have been freed by the time we get to this point SharedMemory::~SharedMemory() { - LOGTRACE("%s", __PRETTY_FUNCTION__); + // printf("%s", __PRETTY_FUNCTION__); if (m_shared_mem != nullptr) { - if (munmap(m_shared_mem, sizeof(lockable_data_t)) == 0) { - LOGTRACE("munmap successful"); - } else { - LOGWARN("munmap NOT successful ERROR!!!"); + if (munmap(m_shared_mem, sizeof(lockable_data_t)) != 0) { + printf("WARNING: munmap NOT successful!\n"); } } - - LOGTRACE("%s Unlinking shared memory", __PRETTY_FUNCTION__); - if (shm_unlink(m_name.c_str()) == 0) { - LOGTRACE("shm_unlink success"); - } else { - LOGWARN("shm_unlink failed!!!"); + if (m_primary) { + // printf("%s Unlinking shared memory", __PRETTY_FUNCTION__); + if (shm_unlink(m_name.c_str()) != 0) { + printf("WARNING: shm_unlink failed!!!\n"); + } } } \ No newline at end of file diff --git a/cpp/shared/shared_memory.h b/cpp/shared/shared_memory.h index f4e3350d..5c005f2a 100644 --- a/cpp/shared/shared_memory.h +++ b/cpp/shared/shared_memory.h @@ -21,7 +21,7 @@ class SharedMemory { public: - SharedMemory(std::string); + SharedMemory(std::string, bool is_primary=false); ~SharedMemory(); inline uint32_t get() const @@ -48,6 +48,10 @@ class SharedMemory } } + inline bool is_valid(){ + return m_valid; + } + private: typedef struct lockable_data { mutable std::shared_mutex mutex_; @@ -57,6 +61,7 @@ class SharedMemory lockable_data_t* m_shared_mem; bool m_valid; + bool m_primary; int m_fd_shared_mem; std::string m_name; };