diff --git a/.gitignore b/.gitignore index f9714d4f..bdf7aae8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ messages.pot messages.mo report.xml +# Intermediate files from astyle +*.orig + docker/docker-compose.override.yml /docker/volumes/images/* !/docker/volumes/images/.gitkeep diff --git a/src/raspberrypi/.clang-format b/src/raspberrypi/.clang-format new file mode 100644 index 00000000..5f33f52d --- /dev/null +++ b/src/raspberrypi/.clang-format @@ -0,0 +1,11 @@ +BasedOnStyle: Microsoft +IndentWidth: 4 +AlwaysBreakAfterReturnType: None +AllowShortFunctionsOnASingleLine: Empty +KeepEmptyLinesAtTheStartOfBlocks: false +BreakBeforeBraces: Linux +AlignEscapedNewlines: Left +AlignTrailingComments: True +AllowShortEnumsOnASingleLine: True +AlignConsecutiveAssignments: Consecutive +ColumnLimit: 120 \ No newline at end of file diff --git a/src/raspberrypi/.vscode/launch.json b/src/raspberrypi/.vscode/launch.json index e3cd4037..f3a2f763 100644 --- a/src/raspberrypi/.vscode/launch.json +++ b/src/raspberrypi/.vscode/launch.json @@ -5,7 +5,7 @@ "version": "0.2.0", "configurations": [ { - "name": "(gdb) Launch", + "name": "rascsi (gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/bin/fullspec/rascsi", @@ -24,6 +24,30 @@ "ignoreFailures": true } ] - } + }, + { + "name": "rascsi_test (gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/bin/fullspec/rascsi_test", + "args": [], + "stopAtEntry": true, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, ] -} +} \ No newline at end of file diff --git a/src/raspberrypi/.vscode/settings.json b/src/raspberrypi/.vscode/settings.json index 5ba85824..aeb05376 100644 --- a/src/raspberrypi/.vscode/settings.json +++ b/src/raspberrypi/.vscode/settings.json @@ -9,6 +9,8 @@ "ratio": "cpp", "tuple": "cpp", "type_traits": "cpp", - "utility": "cpp" + "utility": "cpp", + "cstdint": "cpp", + "stdexcept": "cpp" } } \ No newline at end of file diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 9a7f25a4..81df7e83 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -7,6 +7,8 @@ CROSS_COMPILE = CXX = $(CROSS_COMPILE)g++ +AR = $(CROSS_COMPILE)ar +RANLIB = $(CROSS_COMPILE)ranlib ## DEBUG=1 : A Debug build includes the debugger symbols ## and disables compiler optimization. Typically, diff --git a/src/raspberrypi/controllers/abstract_controller.h b/src/raspberrypi/controllers/abstract_controller.h index 0c0c3809..1ec70aed 100644 --- a/src/raspberrypi/controllers/abstract_controller.h +++ b/src/raspberrypi/controllers/abstract_controller.h @@ -55,7 +55,7 @@ public: uint32_t length; // Transfer remaining length }; - AbstractController(BUS& bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {} + AbstractController(shared_ptr bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {} ~AbstractController() override = default; virtual void Error(scsi_defs::sense_key, scsi_defs::asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION, @@ -108,7 +108,7 @@ private: int target_id; - BUS& bus; + shared_ptr bus; int max_luns; diff --git a/src/raspberrypi/controllers/controller_manager.h b/src/raspberrypi/controllers/controller_manager.h index 3bcd1e66..6ee142d1 100644 --- a/src/raspberrypi/controllers/controller_manager.h +++ b/src/raspberrypi/controllers/controller_manager.h @@ -23,13 +23,13 @@ class PrimaryDevice; class ControllerManager { - BUS& bus; + std::shared_ptr bus; unordered_map> controllers; public: - explicit ControllerManager(BUS& bus) : bus(bus) {} + explicit ControllerManager(std::shared_ptr bus) : bus(bus) {} ~ControllerManager() = default; // Maximum number of controller devices diff --git a/src/raspberrypi/controllers/scsi_controller.cpp b/src/raspberrypi/controllers/scsi_controller.cpp index 483e72e9..031e82c4 100644 --- a/src/raspberrypi/controllers/scsi_controller.cpp +++ b/src/raspberrypi/controllers/scsi_controller.cpp @@ -27,7 +27,7 @@ using namespace scsi_defs; -ScsiController::ScsiController(BUS& bus, int target_id) : AbstractController(bus, target_id, LUN_MAX) +ScsiController::ScsiController(shared_ptr bus, int target_id) : AbstractController(bus, target_id, LUN_MAX) { // The initial buffer size will default to either the default buffer size OR // the size of an Ethernet message, whichever is larger. @@ -51,17 +51,17 @@ void ScsiController::Reset() BUS::phase_t ScsiController::Process(int id) { // Get bus information - bus.Acquire(); + bus->Acquire(); // Check to see if the reset signal was asserted - if (bus.GetRST()) { + if (bus->GetRST()) { LOGWARN("RESET signal received!") // Reset the controller Reset(); // Reset the bus - bus.Reset(); + bus->Reset(); return GetPhase(); } @@ -83,7 +83,7 @@ BUS::phase_t ScsiController::Process(int id) LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__) Reset(); - bus.Reset(); + bus->Reset(); BusFree(); } @@ -98,11 +98,11 @@ void ScsiController::BusFree() SetPhase(BUS::phase_t::busfree); - bus.SetREQ(false); - bus.SetMSG(false); - bus.SetCD(false); - bus.SetIO(false); - bus.SetBSY(false); + bus->SetREQ(false); + bus->SetMSG(false); + bus->SetCD(false); + bus->SetIO(false); + bus->SetBSY(false); // Initialize status and message SetStatus(status::GOOD); @@ -145,7 +145,7 @@ void ScsiController::BusFree() } // Move to selection phase - if (bus.GetSEL() && !bus.GetBSY()) { + if (bus->GetSEL() && !bus->GetBSY()) { Selection(); } } @@ -154,7 +154,7 @@ void ScsiController::Selection() { if (!IsSelection()) { // A different device controller was selected - if (int id = 1 << GetTargetId(); ((int)bus.GetDAT() & id) == 0) { + if (int id = 1 << GetTargetId(); ((int)bus->GetDAT() & id) == 0) { return; } @@ -168,14 +168,14 @@ void ScsiController::Selection() SetPhase(BUS::phase_t::selection); // Raise BSY and respond - bus.SetBSY(true); + bus->SetBSY(true); return; } // Selection completed - if (!bus.GetSEL() && bus.GetBSY()) { + if (!bus->GetSEL() && bus->GetBSY()) { // Message out phase if ATN=1, otherwise command phase - if (bus.GetATN()) { + if (bus->GetATN()) { MsgOut(); } else { Command(); @@ -190,11 +190,11 @@ void ScsiController::Command() SetPhase(BUS::phase_t::command); - bus.SetMSG(false); - bus.SetCD(true); - bus.SetIO(false); + bus->SetMSG(false); + bus->SetCD(true); + bus->SetIO(false); - const int actual_count = bus.CommandHandShake(GetBuffer().data()); + const int actual_count = bus->CommandHandShake(GetBuffer().data()); const int command_byte_count = GPIOBUS::GetCommandByteCount(GetBuffer()[0]); // If not able to receive all, move to the status phase @@ -308,9 +308,9 @@ void ScsiController::Status() SetPhase(BUS::phase_t::status); // Signal line operated by the target - bus.SetMSG(false); - bus.SetCD(true); - bus.SetIO(true); + bus->SetMSG(false); + bus->SetCD(true); + bus->SetIO(true); // Data transfer is 1 byte x 1 block ResetOffset(); @@ -331,9 +331,9 @@ void ScsiController::MsgIn() SetPhase(BUS::phase_t::msgin); - bus.SetMSG(true); - bus.SetCD(true); - bus.SetIO(true); + bus->SetMSG(true); + bus->SetCD(true); + bus->SetIO(true); ResetOffset(); return; @@ -358,9 +358,9 @@ void ScsiController::MsgOut() SetPhase(BUS::phase_t::msgout); - bus.SetMSG(true); - bus.SetCD(true); - bus.SetIO(false); + bus->SetMSG(true); + bus->SetCD(true); + bus->SetIO(false); // Data transfer is 1 byte x 1 block ResetOffset(); @@ -391,9 +391,9 @@ void ScsiController::DataIn() SetPhase(BUS::phase_t::datain); - bus.SetMSG(false); - bus.SetCD(false); - bus.SetIO(true); + bus->SetMSG(false); + bus->SetCD(false); + bus->SetIO(true); ResetOffset(); @@ -422,9 +422,9 @@ void ScsiController::DataOut() SetPhase(BUS::phase_t::dataout); // Signal line operated by the target - bus.SetMSG(false); - bus.SetCD(false); - bus.SetIO(false); + bus->SetMSG(false); + bus->SetCD(false); + bus->SetIO(false); ResetOffset(); return; @@ -436,12 +436,12 @@ void ScsiController::DataOut() void ScsiController::Error(sense_key sense_key, asc asc, status status) { // Get bus information - bus.Acquire(); + bus->Acquire(); // Reset check - if (bus.GetRST()) { + if (bus->GetRST()) { Reset(); - bus.Reset(); + bus->Reset(); return; } @@ -485,8 +485,8 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status) void ScsiController::Send() { - assert(!bus.GetREQ()); - assert(bus.GetIO()); + assert(!bus->GetREQ()); + assert(bus->GetIO()); if (HasValidLength()) { LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(GetOffset()) + ", length " @@ -494,7 +494,7 @@ void ScsiController::Send() // TODO The delay has to be taken from ctrl.unit[lun], but as there are currently no Daynaport drivers for // LUNs other than 0 this work-around works. - if (const int len = bus.SendHandShake(GetBuffer().data() + ctrl.offset, ctrl.length, + if (const int len = bus->SendHandShake(GetBuffer().data() + ctrl.offset, ctrl.length, HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0); len != (int)ctrl.length) { // If you cannot send all, move to status phase @@ -581,15 +581,15 @@ void ScsiController::Receive() LOGTRACE("%s",__PRETTY_FUNCTION__) // REQ is low - assert(!bus.GetREQ()); - assert(!bus.GetIO()); + assert(!bus->GetREQ()); + assert(!bus->GetIO()); // Length != 0 if received if (HasValidLength()) { LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length) // If not able to receive all, move to status phase - if (int len = bus.ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length); + if (int len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length); len != (int)ctrl.length) { LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, ctrl.length, len) Error(sense_key::ABORTED_COMMAND); @@ -687,14 +687,14 @@ bool ScsiController::XferMsg(int msg) void ScsiController::ReceiveBytes() { - assert(!bus.GetREQ()); - assert(!bus.GetIO()); + assert(!bus->GetREQ()); + assert(!bus->GetIO()); if (HasValidLength()) { LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length) // If not able to receive all, move to status phase - if (uint32_t len = bus.ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length); + if (uint32_t len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length); len != ctrl.length) { LOGERROR("%s Not able to receive %d bytes of data, only received %d", __PRETTY_FUNCTION__, ctrl.length, len) @@ -1040,7 +1040,7 @@ void ScsiController::ParseMessage() void ScsiController::ProcessMessage() { // Continue message out phase as long as ATN keeps asserting - if (bus.GetATN()) { + if (bus->GetATN()) { // Data transfer is 1 byte x 1 block ResetOffset(); SetLength(1); diff --git a/src/raspberrypi/controllers/scsi_controller.h b/src/raspberrypi/controllers/scsi_controller.h index 5044d647..3d545b7d 100644 --- a/src/raspberrypi/controllers/scsi_controller.h +++ b/src/raspberrypi/controllers/scsi_controller.h @@ -54,7 +54,7 @@ public: // Maximum number of logical units static const int LUN_MAX = 32; - ScsiController(BUS&, int); + ScsiController(shared_ptr, int); ~ScsiController() override = default; void Reset() override; diff --git a/src/raspberrypi/hal/gpiobus.cpp b/src/raspberrypi/hal/gpiobus.cpp index 7337b808..9d02e36a 100644 --- a/src/raspberrypi/hal/gpiobus.cpp +++ b/src/raspberrypi/hal/gpiobus.cpp @@ -10,669 +10,421 @@ // //--------------------------------------------------------------------------- -#include -#include -#include -#include "os.h" #include "hal/gpiobus.h" -#include "hal/systimer.h" #include "config.h" +#include "hal/sbc_version.h" +#include "hal/systimer.h" #include "log.h" +#include "os.h" #include +#include +#include +#include #ifdef __linux__ #include #endif +#if defined CONNECT_TYPE_STANDARD +#include "hal/gpiobus_standard.h" +#elif defined CONNECT_TYPE_FULLSPEC +#include "hal/gpiobus_fullspec.h" +#elif defined CONNECT_TYPE_AIBOM +#include "hal/gpiobus_aibom.h" +#elif defined CONNECT_TYPE_GAMERNIUM +#include "hal/gpiobus_gamernium.h" +#else +#error Invalid connection type or none specified +#endif + +//--------------------------------------------------------------------------- +// +// Constant declarations (bus control timing) +// +//--------------------------------------------------------------------------- +// SCSI Bus timings taken from: +// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html +[[maybe_unused]] const static int SCSI_DELAY_ARBITRATION_DELAY_NS = 2400; +[[maybe_unused]] const static int SCSI_DELAY_ASSERTION_PERIOD_NS = 90; +[[maybe_unused]] const static int SCSI_DELAY_BUS_CLEAR_DELAY_NS = 800; +[[maybe_unused]] const static int SCSI_DELAY_BUS_FREE_DELAY_NS = 800; +[[maybe_unused]] const static int SCSI_DELAY_BUS_SET_DELAY_NS = 1800; +[[maybe_unused]] const static int SCSI_DELAY_BUS_SETTLE_DELAY_NS = 400; +[[maybe_unused]] const static int SCSI_DELAY_CABLE_SKEW_DELAY_NS = 10; +[[maybe_unused]] const static int SCSI_DELAY_DATA_RELEASE_DELAY_NS = 400; +[[maybe_unused]] const static int SCSI_DELAY_DESKEW_DELAY_NS = 45; +[[maybe_unused]] const static int SCSI_DELAY_DISCONNECTION_DELAY_US = 200; +[[maybe_unused]] const static int SCSI_DELAY_HOLD_TIME_NS = 45; +[[maybe_unused]] const static int SCSI_DELAY_NEGATION_PERIOD_NS = 90; +[[maybe_unused]] const static int SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S = 10; // (recommended) +[[maybe_unused]] const static int SCSI_DELAY_RESET_TO_SELECTION_TIME_US = 250 * 1000; // (recommended) +[[maybe_unused]] const static int SCSI_DELAY_RESET_HOLD_TIME_US = 25; +[[maybe_unused]] const static int SCSI_DELAY_SELECTION_ABORT_TIME_US = 200; +[[maybe_unused]] const static int SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS = 250 * 1000; // (recommended) +[[maybe_unused]] const static int SCSI_DELAY_FAST_ASSERTION_PERIOD_NS = 30; +[[maybe_unused]] const static int SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS = 5; +[[maybe_unused]] const static int SCSI_DELAY_FAST_DESKEW_DELAY_NS = 20; +[[maybe_unused]] const static int SCSI_DELAY_FAST_HOLD_TIME_NS = 10; +[[maybe_unused]] const static int SCSI_DELAY_FAST_NEGATION_PERIOD_NS = 30; + +// The DaynaPort SCSI Link do a short delay in the middle of transfering +// a packet. This is the number of uS that will be delayed between the +// header and the actual data. +const static int SCSI_DELAY_SEND_DATA_DAYNAPORT_US = 100; + using namespace std; -#ifdef __linux__ -//--------------------------------------------------------------------------- -// -// imported from bcm_host.c -// -//--------------------------------------------------------------------------- -static uint32_t get_dt_ranges(const char *filename, DWORD offset) -{ - uint32_t address = ~0; - if (FILE *fp = fopen(filename, "rb"); fp) { - fseek(fp, offset, SEEK_SET); - if (array buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) { - address = (int)buf[0] << 24 | (int)buf[1] << 16 | (int)buf[2] << 8 | (int)buf[3] << 0; - } - fclose(fp); - } - return address; -} - -uint32_t bcm_host_get_peripheral_address() -{ - uint32_t address = get_dt_ranges("/proc/device-tree/soc/ranges", 4); - if (address == 0) { - address = get_dt_ranges("/proc/device-tree/soc/ranges", 8); - } - address = (address == (uint32_t)~0) ? 0x20000000 : address; - return address; -} -#endif - -#ifdef __NetBSD__ -// Assume the Raspberry Pi series and estimate the address from CPU -uint32_t bcm_host_get_peripheral_address() -{ - array buf; - size_t len = buf.size(); - DWORD address; - - if (sysctlbyname("hw.model", buf.data(), &len, NULL, 0) || - strstr(buf, "ARM1176JZ-S") != buf.data()) { - // Failed to get CPU model || Not BCM2835 - // use the address of BCM283[67] - address = 0x3f000000; - } else { - // Use BCM2835 address - address = 0x20000000; - } - printf("Peripheral address : 0x%lx\n", address); - return address; -} -#endif - +// Nothing SBC hardware specific should be done in this function bool GPIOBUS::Init(mode_e mode) { - // Save operation mode - actmode = mode; - -#if defined(__x86_64__) || defined(__X86__) - return true; -#else - int i; -#ifdef USE_SEL_EVENT_ENABLE - epoll_event ev = {}; -#endif - - // Get the base address - baseaddr = (uint32_t)bcm_host_get_peripheral_address(); - - // Open /dev/mem - int fd = open("/dev/mem", O_RDWR | O_SYNC); - if (fd == -1) { - LOGERROR("Error: Unable to open /dev/mem. Are you running as root?") - return false; - } - - // Map peripheral region memory - void *map = mmap(NULL, 0x1000100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr); - if (map == MAP_FAILED) { - LOGERROR("Error: Unable to map memory") - close(fd); - return false; - } - - // Determine the type of raspberry pi from the base address - if (baseaddr == 0xfe000000) { - rpitype = 4; - } else if (baseaddr == 0x3f000000) { - rpitype = 2; - } else { - rpitype = 1; - } - - // GPIO - gpio = (DWORD *)map; - gpio += GPIO_OFFSET / sizeof(DWORD); - level = &gpio[GPIO_LEV_0]; - - // PADS - pads = (DWORD *)map; - pads += PADS_OFFSET / sizeof(DWORD); - - // System timer - SysTimer::Init( - (DWORD *)map + SYST_OFFSET / sizeof(DWORD), - (DWORD *)map + ARMT_OFFSET / sizeof(DWORD)); - - // Interrupt controller - irpctl = (DWORD *)map; - irpctl += IRPT_OFFSET / sizeof(DWORD); - - // Quad-A7 control - qa7regs = (DWORD *)map; - qa7regs += QA7_OFFSET / sizeof(DWORD); - - // Map GIC memory - if (rpitype == 4) { - map = mmap(NULL, 8192, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, ARM_GICD_BASE); - if (map == MAP_FAILED) { - close(fd); - return false; - } - gicd = (DWORD *)map; - gicc = (DWORD *)map; - gicc += (ARM_GICC_BASE - ARM_GICD_BASE) / sizeof(DWORD); - } else { - gicd = NULL; - gicc = NULL; - } - close(fd); - - // Set Drive Strength to 16mA - DrvConfig(7); - - // Set pull up/pull down -#if SIGNAL_CONTROL_MODE == 0 - int pullmode = GPIO_PULLNONE; -#elif SIGNAL_CONTROL_MODE == 1 - int pullmode = GPIO_PULLUP; -#else - int pullmode = GPIO_PULLDOWN; -#endif - - // Initialize all signals - for (i = 0; SignalTable[i] >= 0; i++) { - int j = SignalTable[i]; - PinSetSignal(j, OFF); - PinConfig(j, GPIO_INPUT); - PullConfig(j, pullmode); - } - - // Set control signals - PinSetSignal(PIN_ACT, OFF); - PinSetSignal(PIN_TAD, OFF); - PinSetSignal(PIN_IND, OFF); - PinSetSignal(PIN_DTD, OFF); - PinConfig(PIN_ACT, GPIO_OUTPUT); - PinConfig(PIN_TAD, GPIO_OUTPUT); - PinConfig(PIN_IND, GPIO_OUTPUT); - PinConfig(PIN_DTD, GPIO_OUTPUT); - - // Set the ENABLE signal - // This is used to show that the application is running - PinSetSignal(PIN_ENB, ENB_OFF); - PinConfig(PIN_ENB, GPIO_OUTPUT); - - // GPFSEL backup - gpfsel[0] = gpio[GPIO_FSEL_0]; - gpfsel[1] = gpio[GPIO_FSEL_1]; - gpfsel[2] = gpio[GPIO_FSEL_2]; - gpfsel[3] = gpio[GPIO_FSEL_3]; - - // Initialize SEL signal interrupt -#ifdef USE_SEL_EVENT_ENABLE - // GPIO chip open - fd = open("/dev/gpiochip0", 0); - if (fd == -1) { - LOGERROR("Unable to open /dev/gpiochip0. Is RaSCSI already running?") - return false; - } - - // Event request setting - strcpy(selevreq.consumer_label, "RaSCSI"); - selevreq.lineoffset = PIN_SEL; - selevreq.handleflags = GPIOHANDLE_REQUEST_INPUT; -#if SIGNAL_CONTROL_MODE < 2 - selevreq.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; -#else - selevreq.eventflags = GPIOEVENT_REQUEST_RISING_EDGE; -#endif // SIGNAL_CONTROL_MODE - - //Get event request - if (ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &selevreq) == -1) { - LOGERROR("Unable to register event request. Is RaSCSI already running?") - close(fd); - return false; - } - - // Close GPIO chip file handle - close(fd); - - // epoll initialization - epfd = epoll_create(1); - ev.events = EPOLLIN | EPOLLPRI; - ev.data.fd = selevreq.fd; - epoll_ctl(epfd, EPOLL_CTL_ADD, selevreq.fd, &ev); -#else - // Edge detection setting -#if SIGNAL_CONTROL_MODE == 2 - gpio[GPIO_AREN_0] = 1 << PIN_SEL; -#else - gpio[GPIO_AFEN_0] = 1 << PIN_SEL; -#endif // SIGNAL_CONTROL_MODE - - // Clear event - gpio[GPIO_EDS_0] = 1 << PIN_SEL; - - // Register interrupt handler - setIrqFuncAddress(IrqHandler); - - // GPIO interrupt setting - if (rpitype == 4) { - // GIC Invalid - gicd[GICD_CTLR] = 0; - - // Route all interupts to core 0 - for (i = 0; i < 8; i++) { - gicd[GICD_ICENABLER0 + i] = 0xffffffff; - gicd[GICD_ICPENDR0 + i] = 0xffffffff; - gicd[GICD_ICACTIVER0 + i] = 0xffffffff; - } - for (i = 0; i < 64; i++) { - gicd[GICD_IPRIORITYR0 + i] = 0xa0a0a0a0; - gicd[GICD_ITARGETSR0 + i] = 0x01010101; - } - - // Set all interrupts as level triggers - for (i = 0; i < 16; i++) { - gicd[GICD_ICFGR0 + i] = 0; - } - - // GIC Invalid - gicd[GICD_CTLR] = 1; - - // Enable CPU interface for core 0 - gicc[GICC_PMR] = 0xf0; - gicc[GICC_CTLR] = 1; - - // Enable interrupts - gicd[GICD_ISENABLER0 + (GIC_GPIO_IRQ / 32)] = - 1 << (GIC_GPIO_IRQ % 32); - } else { - // Enable interrupts - irpctl[IRPT_ENB_IRQ_2] = (1 << (GPIO_IRQ % 32)); - } -#endif // USE_SEL_EVENT_ENABLE - - // Create work table - MakeTable(); - - // Finally, enable ENABLE - // Show the user that this app is running - SetControl(PIN_ENB, ENB_ON); - - return true; -#endif // ifdef __x86_64__ || __X86__ - + GPIO_FUNCTION_TRACE + // Save operation mode + actmode = mode; + return true; } void GPIOBUS::Cleanup() { #if defined(__x86_64__) || defined(__X86__) - return; + return; #else - // Release SEL signal interrupt + // Release SEL signal interrupt #ifdef USE_SEL_EVENT_ENABLE - close(selevreq.fd); -#endif // USE_SEL_EVENT_ENABLE + close(selevreq.fd); +#endif // USE_SEL_EVENT_ENABLE - // 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); + // 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); - // 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); - } + // 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); + } - // Set drive strength back to 8mA - DrvConfig(3); + // Set drive strength back to 8mA + DrvConfig(3); #endif // ifdef __x86_64__ || __X86__ } void GPIOBUS::Reset() { + GPIO_FUNCTION_TRACE #if defined(__x86_64__) || defined(__X86__) - return; + return; #else - int i; - int j; + int i; + int j; - // Turn off active signal - SetControl(PIN_ACT, ACT_OFF); + // Turn off active signal + SetControl(PIN_ACT, ACT_OFF); - // Set all signals to off - for (i = 0;; i++) { - j = SignalTable[i]; - if (j < 0) { - break; - } + // Set all signals to off + for (i = 0;; i++) { + j = SignalTable[i]; + if (j < 0) { + break; + } - SetSignal(j, OFF); - } + SetSignal(j, OFF); + } - if (actmode == mode_e::TARGET) { - // Target mode + if (actmode == mode_e::TARGET) { + // Target mode - // Set target signal to input - SetControl(PIN_TAD, TAD_IN); - SetMode(PIN_BSY, IN); - SetMode(PIN_MSG, IN); - SetMode(PIN_CD, IN); - SetMode(PIN_REQ, IN); - SetMode(PIN_IO, IN); + // Set target signal to input + SetControl(PIN_TAD, TAD_IN); + SetMode(PIN_BSY, IN); + SetMode(PIN_MSG, IN); + SetMode(PIN_CD, IN); + SetMode(PIN_REQ, IN); + SetMode(PIN_IO, IN); - // Set the initiator signal to input - SetControl(PIN_IND, IND_IN); - SetMode(PIN_SEL, IN); - SetMode(PIN_ATN, IN); - SetMode(PIN_ACK, IN); - SetMode(PIN_RST, IN); + // Set the initiator signal to input + SetControl(PIN_IND, IND_IN); + SetMode(PIN_SEL, IN); + SetMode(PIN_ATN, IN); + SetMode(PIN_ACK, IN); + SetMode(PIN_RST, IN); - // Set data bus signals to input - SetControl(PIN_DTD, DTD_IN); - SetMode(PIN_DT0, IN); - SetMode(PIN_DT1, IN); - SetMode(PIN_DT2, IN); - SetMode(PIN_DT3, IN); - SetMode(PIN_DT4, IN); - SetMode(PIN_DT5, IN); - SetMode(PIN_DT6, IN); - SetMode(PIN_DT7, IN); - SetMode(PIN_DP, IN); - } else { - // Initiator mode + // Set data bus signals to input + SetControl(PIN_DTD, DTD_IN); + SetMode(PIN_DT0, IN); + SetMode(PIN_DT1, IN); + SetMode(PIN_DT2, IN); + SetMode(PIN_DT3, IN); + SetMode(PIN_DT4, IN); + SetMode(PIN_DT5, IN); + SetMode(PIN_DT6, IN); + SetMode(PIN_DT7, IN); + SetMode(PIN_DP, IN); + } else { + // Initiator mode - // Set target signal to input - SetControl(PIN_TAD, TAD_IN); - SetMode(PIN_BSY, IN); - SetMode(PIN_MSG, IN); - SetMode(PIN_CD, IN); - SetMode(PIN_REQ, IN); - SetMode(PIN_IO, IN); + // Set target signal to input + SetControl(PIN_TAD, TAD_IN); + SetMode(PIN_BSY, IN); + SetMode(PIN_MSG, IN); + SetMode(PIN_CD, IN); + SetMode(PIN_REQ, IN); + SetMode(PIN_IO, IN); - // Set the initiator signal to output - SetControl(PIN_IND, IND_OUT); - SetMode(PIN_SEL, OUT); - SetMode(PIN_ATN, OUT); - SetMode(PIN_ACK, OUT); - SetMode(PIN_RST, OUT); + // Set the initiator signal to output + SetControl(PIN_IND, IND_OUT); + SetMode(PIN_SEL, OUT); + SetMode(PIN_ATN, OUT); + SetMode(PIN_ACK, OUT); + SetMode(PIN_RST, OUT); - // Set the data bus signals to output - SetControl(PIN_DTD, DTD_OUT); - SetMode(PIN_DT0, OUT); - SetMode(PIN_DT1, OUT); - SetMode(PIN_DT2, OUT); - SetMode(PIN_DT3, OUT); - SetMode(PIN_DT4, OUT); - SetMode(PIN_DT5, OUT); - SetMode(PIN_DT6, OUT); - SetMode(PIN_DT7, OUT); - SetMode(PIN_DP, OUT); - } + // Set the data bus signals to output + SetControl(PIN_DTD, DTD_OUT); + SetMode(PIN_DT0, OUT); + SetMode(PIN_DT1, OUT); + SetMode(PIN_DT2, OUT); + SetMode(PIN_DT3, OUT); + SetMode(PIN_DT4, OUT); + SetMode(PIN_DT5, OUT); + SetMode(PIN_DT6, OUT); + SetMode(PIN_DT7, OUT); + SetMode(PIN_DP, OUT); + } - // Initialize all signals - signals = 0; + // Initialize all signals + signals = 0; #endif // ifdef __x86_64__ || __X86__ } void GPIOBUS::SetENB(bool ast) { - PinSetSignal(PIN_ENB, ast ? ENB_ON : ENB_OFF); + GPIO_FUNCTION_TRACE + PinSetSignal(PIN_ENB, ast ? ENB_ON : ENB_OFF); } bool GPIOBUS::GetBSY() const { - return GetSignal(PIN_BSY); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_BSY); } void GPIOBUS::SetBSY(bool ast) { - // Set BSY signal - SetSignal(PIN_BSY, ast); + GPIO_FUNCTION_TRACE + // Set BSY signal + SetSignal(PIN_BSY, ast); - if (actmode == mode_e::TARGET) { - if (ast) { - // Turn on ACTIVE signal - SetControl(PIN_ACT, ACT_ON); + if (actmode == mode_e::TARGET) { + if (ast) { + // Turn on ACTIVE signal + SetControl(PIN_ACT, ACT_ON); - // Set Target signal to output - SetControl(PIN_TAD, TAD_OUT); + // Set Target signal to output + SetControl(PIN_TAD, TAD_OUT); - SetMode(PIN_BSY, OUT); - SetMode(PIN_MSG, OUT); - SetMode(PIN_CD, OUT); - SetMode(PIN_REQ, OUT); - SetMode(PIN_IO, OUT); - } else { - // Turn off the ACTIVE signal - SetControl(PIN_ACT, ACT_OFF); + SetMode(PIN_BSY, OUT); + SetMode(PIN_MSG, OUT); + SetMode(PIN_CD, OUT); + SetMode(PIN_REQ, OUT); + SetMode(PIN_IO, OUT); + } else { + // Turn off the ACTIVE signal + SetControl(PIN_ACT, ACT_OFF); - // Set the target signal to input - SetControl(PIN_TAD, TAD_IN); + // Set the target signal to input + SetControl(PIN_TAD, TAD_IN); - SetMode(PIN_BSY, IN); - SetMode(PIN_MSG, IN); - SetMode(PIN_CD, IN); - SetMode(PIN_REQ, IN); - SetMode(PIN_IO, IN); - } - } + SetMode(PIN_BSY, IN); + SetMode(PIN_MSG, IN); + SetMode(PIN_CD, IN); + SetMode(PIN_REQ, IN); + SetMode(PIN_IO, IN); + } + } } bool GPIOBUS::GetSEL() const { - return GetSignal(PIN_SEL); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_SEL); } void GPIOBUS::SetSEL(bool ast) { - if (actmode == mode_e::INITIATOR && ast) { - // Turn on ACTIVE signal - SetControl(PIN_ACT, ACT_ON); - } + GPIO_FUNCTION_TRACE + if (actmode == mode_e::INITIATOR && ast) { + // Turn on ACTIVE signal + SetControl(PIN_ACT, ACT_ON); + } - // Set SEL signal - SetSignal(PIN_SEL, ast); + // Set SEL signal + SetSignal(PIN_SEL, ast); } bool GPIOBUS::GetATN() const { - return GetSignal(PIN_ATN); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_ATN); } void GPIOBUS::SetATN(bool ast) { - SetSignal(PIN_ATN, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_ATN, ast); } bool GPIOBUS::GetACK() const { - return GetSignal(PIN_ACK); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_ACK); } void GPIOBUS::SetACK(bool ast) { - SetSignal(PIN_ACK, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_ACK, ast); } bool GPIOBUS::GetACT() const { - return GetSignal(PIN_ACT); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_ACT); } void GPIOBUS::SetACT(bool ast) { - SetSignal(PIN_ACT, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_ACT, ast); } bool GPIOBUS::GetRST() const { - return GetSignal(PIN_RST); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_RST); } void GPIOBUS::SetRST(bool ast) { - SetSignal(PIN_RST, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_RST, ast); } bool GPIOBUS::GetMSG() const { - return GetSignal(PIN_MSG); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_MSG); } void GPIOBUS::SetMSG(bool ast) { - SetSignal(PIN_MSG, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_MSG, ast); } bool GPIOBUS::GetCD() const { - return GetSignal(PIN_CD); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_CD); } void GPIOBUS::SetCD(bool ast) { - SetSignal(PIN_CD, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_CD, ast); } bool GPIOBUS::GetIO() { - bool ast = GetSignal(PIN_IO); + GPIO_FUNCTION_TRACE + bool ast = GetSignal(PIN_IO); - if (actmode == mode_e::INITIATOR) { - // Change the data input/output direction by IO signal - if (ast) { - SetControl(PIN_DTD, DTD_IN); - SetMode(PIN_DT0, IN); - SetMode(PIN_DT1, IN); - SetMode(PIN_DT2, IN); - SetMode(PIN_DT3, IN); - SetMode(PIN_DT4, IN); - SetMode(PIN_DT5, IN); - SetMode(PIN_DT6, IN); - SetMode(PIN_DT7, IN); - SetMode(PIN_DP, IN); - } else { - SetControl(PIN_DTD, DTD_OUT); - SetMode(PIN_DT0, OUT); - SetMode(PIN_DT1, OUT); - SetMode(PIN_DT2, OUT); - SetMode(PIN_DT3, OUT); - SetMode(PIN_DT4, OUT); - SetMode(PIN_DT5, OUT); - SetMode(PIN_DT6, OUT); - SetMode(PIN_DT7, OUT); - SetMode(PIN_DP, OUT); - } - } + if (actmode == mode_e::INITIATOR) { + // Change the data input/output direction by IO signal + if (ast) { + SetControl(PIN_DTD, DTD_IN); + SetMode(PIN_DT0, IN); + SetMode(PIN_DT1, IN); + SetMode(PIN_DT2, IN); + SetMode(PIN_DT3, IN); + SetMode(PIN_DT4, IN); + SetMode(PIN_DT5, IN); + SetMode(PIN_DT6, IN); + SetMode(PIN_DT7, IN); + SetMode(PIN_DP, IN); + } else { + SetControl(PIN_DTD, DTD_OUT); + SetMode(PIN_DT0, OUT); + SetMode(PIN_DT1, OUT); + SetMode(PIN_DT2, OUT); + SetMode(PIN_DT3, OUT); + SetMode(PIN_DT4, OUT); + SetMode(PIN_DT5, OUT); + SetMode(PIN_DT6, OUT); + SetMode(PIN_DT7, OUT); + SetMode(PIN_DP, OUT); + } + } - return ast; + return ast; } void GPIOBUS::SetIO(bool ast) { - SetSignal(PIN_IO, ast); + GPIO_FUNCTION_TRACE + SetSignal(PIN_IO, ast); - if (actmode == mode_e::TARGET) { - // Change the data input/output direction by IO signal - if (ast) { - SetControl(PIN_DTD, DTD_OUT); - SetDAT(0); - SetMode(PIN_DT0, OUT); - SetMode(PIN_DT1, OUT); - SetMode(PIN_DT2, OUT); - SetMode(PIN_DT3, OUT); - SetMode(PIN_DT4, OUT); - SetMode(PIN_DT5, OUT); - SetMode(PIN_DT6, OUT); - SetMode(PIN_DT7, OUT); - SetMode(PIN_DP, OUT); - } else { - SetControl(PIN_DTD, DTD_IN); - SetMode(PIN_DT0, IN); - SetMode(PIN_DT1, IN); - SetMode(PIN_DT2, IN); - SetMode(PIN_DT3, IN); - SetMode(PIN_DT4, IN); - SetMode(PIN_DT5, IN); - SetMode(PIN_DT6, IN); - SetMode(PIN_DT7, IN); - SetMode(PIN_DP, IN); - } - } + if (actmode == mode_e::TARGET) { + // Change the data input/output direction by IO signal + if (ast) { + SetControl(PIN_DTD, DTD_OUT); + SetDAT(0); + SetMode(PIN_DT0, OUT); + SetMode(PIN_DT1, OUT); + SetMode(PIN_DT2, OUT); + SetMode(PIN_DT3, OUT); + SetMode(PIN_DT4, OUT); + SetMode(PIN_DT5, OUT); + SetMode(PIN_DT6, OUT); + SetMode(PIN_DT7, OUT); + SetMode(PIN_DP, OUT); + } else { + SetControl(PIN_DTD, DTD_IN); + SetMode(PIN_DT0, IN); + SetMode(PIN_DT1, IN); + SetMode(PIN_DT2, IN); + SetMode(PIN_DT3, IN); + SetMode(PIN_DT4, IN); + SetMode(PIN_DT5, IN); + SetMode(PIN_DT6, IN); + SetMode(PIN_DT7, IN); + SetMode(PIN_DP, IN); + } + } } bool GPIOBUS::GetREQ() const { - return GetSignal(PIN_REQ); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_REQ); } void GPIOBUS::SetREQ(bool ast) { - SetSignal(PIN_REQ, ast); -} - -//--------------------------------------------------------------------------- -// -// Get data signals -// -//--------------------------------------------------------------------------- -BYTE GPIOBUS::GetDAT() -{ - uint32_t data = Acquire(); - data = - ((data >> (PIN_DT0 - 0)) & (1 << 0)) | - ((data >> (PIN_DT1 - 1)) & (1 << 1)) | - ((data >> (PIN_DT2 - 2)) & (1 << 2)) | - ((data >> (PIN_DT3 - 3)) & (1 << 3)) | - ((data >> (PIN_DT4 - 4)) & (1 << 4)) | - ((data >> (PIN_DT5 - 5)) & (1 << 5)) | - ((data >> (PIN_DT6 - 6)) & (1 << 6)) | - ((data >> (PIN_DT7 - 7)) & (1 << 7)); - - return (BYTE)data; -} - -//--------------------------------------------------------------------------- -// -// Set data signals -// -//--------------------------------------------------------------------------- -void GPIOBUS::SetDAT(BYTE dat) -{ - // Write to port -#if SIGNAL_CONTROL_MODE == 0 - DWORD fsel = gpfsel[0]; - fsel &= tblDatMsk[0][dat]; - fsel |= tblDatSet[0][dat]; - if (fsel != gpfsel[0]) { - gpfsel[0] = fsel; - gpio[GPIO_FSEL_0] = fsel; - } - - fsel = gpfsel[1]; - fsel &= tblDatMsk[1][dat]; - fsel |= tblDatSet[1][dat]; - if (fsel != gpfsel[1]) { - gpfsel[1] = fsel; - gpio[GPIO_FSEL_1] = fsel; - } - - fsel = gpfsel[2]; - fsel &= tblDatMsk[2][dat]; - fsel |= tblDatSet[2][dat]; - if (fsel != gpfsel[2]) { - gpfsel[2] = fsel; - gpio[GPIO_FSEL_2] = fsel; - } -#else - gpio[GPIO_CLR_0] = tblDatMsk[dat]; - gpio[GPIO_SET_0] = tblDatSet[dat]; -#endif // SIGNAL_CONTROL_MODE + GPIO_FUNCTION_TRACE + SetSignal(PIN_REQ, ast); } bool GPIOBUS::GetDP() const { - return GetSignal(PIN_DP); + GPIO_FUNCTION_TRACE + return GetSignal(PIN_DP); } //--------------------------------------------------------------------------- @@ -682,119 +434,120 @@ bool GPIOBUS::GetDP() const //--------------------------------------------------------------------------- int GPIOBUS::CommandHandShake(BYTE *buf) { - // Only works in TARGET mode - if (actmode != mode_e::TARGET) { - return 0; - } + GPIO_FUNCTION_TRACE + // Only works in TARGET mode + if (actmode != mode_e::TARGET) { + return 0; + } - DisableIRQ(); + DisableIRQ(); - // Assert REQ signal - SetSignal(PIN_REQ, ON); + // Assert REQ signal + SetSignal(PIN_REQ, ON); - // Wait for ACK signal - bool ret = WaitSignal(PIN_ACK, ON); + // Wait for ACK signal + bool ret = WaitSignal(PIN_ACK, ON); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + // Wait until the signal line stabilizes + SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - // Get data - *buf = GetDAT(); + // Get data + *buf = GetDAT(); - // Disable REQ signal - SetSignal(PIN_REQ, OFF); + // Disable REQ signal + SetSignal(PIN_REQ, OFF); - // Timeout waiting for ACK assertion - if (!ret) { - EnableIRQ(); - return 0; - } + // Timeout waiting for ACK assertion + if (!ret) { + EnableIRQ(); + return 0; + } - // Wait for ACK to clear - ret = WaitSignal(PIN_ACK, OFF); + // Wait for ACK to clear + ret = WaitSignal(PIN_ACK, OFF); - // Timeout waiting for ACK to clear - if (!ret) { - EnableIRQ(); - return 0; - } + // Timeout waiting for ACK to clear + if (!ret) { + EnableIRQ(); + return 0; + } - // The ICD AdSCSI ST, AdSCSI Plus ST and AdSCSI Micro ST host adapters allow SCSI devices to be connected - // to the ACSI bus of Atari ST/TT computers and some clones. ICD-aware drivers prepend a $1F byte in front - // of the CDB (effectively resulting in a custom SCSI command) in order to get access to the full SCSI - // command set. Native ACSI is limited to the low SCSI command classes with command bytes < $20. - // Most other host adapters (e.g. LINK96/97 and the one by Inventronik) and also several devices (e.g. - // UltraSatan or GigaFile) that can directly be connected to the Atari's ACSI port also support ICD - // semantics. I fact, these semantics have become a standard in the Atari world. + // The ICD AdSCSI ST, AdSCSI Plus ST and AdSCSI Micro ST host adapters allow SCSI devices to be connected + // to the ACSI bus of Atari ST/TT computers and some clones. ICD-aware drivers prepend a $1F byte in front + // of the CDB (effectively resulting in a custom SCSI command) in order to get access to the full SCSI + // command set. Native ACSI is limited to the low SCSI command classes with command bytes < $20. + // Most other host adapters (e.g. LINK96/97 and the one by Inventronik) and also several devices (e.g. + // UltraSatan or GigaFile) that can directly be connected to the Atari's ACSI port also support ICD + // semantics. I fact, these semantics have become a standard in the Atari world. - // RaSCSI becomes ICD compatible by ignoring the prepended $1F byte before processing the CDB. - if (*buf == 0x1F) { - SetSignal(PIN_REQ, ON); + // RaSCSI becomes ICD compatible by ignoring the prepended $1F byte before processing the CDB. + if (*buf == 0x1F) { + SetSignal(PIN_REQ, ON); - ret = WaitSignal(PIN_ACK, ON); + ret = WaitSignal(PIN_ACK, ON); - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - // Get the actual SCSI command - *buf = GetDAT(); + // Get the actual SCSI command + *buf = GetDAT(); - SetSignal(PIN_REQ, OFF); + SetSignal(PIN_REQ, OFF); - if (!ret) { - EnableIRQ(); - return 0; - } + if (!ret) { + EnableIRQ(); + return 0; + } - WaitSignal(PIN_ACK, OFF); + WaitSignal(PIN_ACK, OFF); - if (!ret) { - EnableIRQ(); - return 0; - } - } + if (!ret) { + EnableIRQ(); + return 0; + } + } - int command_byte_count = GetCommandByteCount(*buf); + int command_byte_count = GetCommandByteCount(*buf); - // Increment buffer pointer - buf++; + // Increment buffer pointer + buf++; - int bytes_received; - for (bytes_received = 1; bytes_received < command_byte_count; bytes_received++) { - // Assert REQ signal - SetSignal(PIN_REQ, ON); + int bytes_received; + for (bytes_received = 1; bytes_received < command_byte_count; bytes_received++) { + // Assert REQ signal + SetSignal(PIN_REQ, ON); - // Wait for ACK signal - ret = WaitSignal(PIN_ACK, ON); + // Wait for ACK signal + ret = WaitSignal(PIN_ACK, ON); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + // Wait until the signal line stabilizes + SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - // Get data - *buf = GetDAT(); + // Get data + *buf = GetDAT(); - // Clear the REQ signal - SetSignal(PIN_REQ, OFF); + // Clear the REQ signal + SetSignal(PIN_REQ, OFF); - // Check for timeout waiting for ACK assertion - if (!ret) { - break; - } + // Check for timeout waiting for ACK assertion + if (!ret) { + break; + } - // Wait for ACK to clear - ret = WaitSignal(PIN_ACK, OFF); + // Wait for ACK to clear + ret = WaitSignal(PIN_ACK, OFF); - // Check for timeout waiting for ACK to clear - if (!ret) { - break; - } + // Check for timeout waiting for ACK to clear + if (!ret) { + break; + } - // Advance the buffer pointer to receive the next byte - buf++; - } + // Advance the buffer pointer to receive the next byte + buf++; + } - EnableIRQ(); + EnableIRQ(); - return bytes_received; + return bytes_received; } //--------------------------------------------------------------------------- @@ -804,97 +557,99 @@ int GPIOBUS::CommandHandShake(BYTE *buf) //--------------------------------------------------------------------------- int GPIOBUS::ReceiveHandShake(BYTE *buf, int count) { - int i; + GPIO_FUNCTION_TRACE - // Disable IRQs - DisableIRQ(); + int i; - if (actmode == mode_e::TARGET) { - for (i = 0; i < count; i++) { - // Assert the REQ signal - SetSignal(PIN_REQ, ON); + // Disable IRQs + DisableIRQ(); - // Wait for ACK - bool ret = WaitSignal(PIN_ACK, ON); + if (actmode == mode_e::TARGET) { + for (i = 0; i < count; i++) { + // Assert the REQ signal + SetSignal(PIN_REQ, ON); - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + // Wait for ACK + bool ret = WaitSignal(PIN_ACK, ON); - // Get data - *buf = GetDAT(); + // Wait until the signal line stabilizes + SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - // Clear the REQ signal - SetSignal(PIN_REQ, OFF); + // Get data + *buf = GetDAT(); - // Check for timeout waiting for ACK signal - if (!ret) { - break; - } + // Clear the REQ signal + SetSignal(PIN_REQ, OFF); - // Wait for ACK to clear - ret = WaitSignal(PIN_ACK, OFF); + // Check for timeout waiting for ACK signal + if (!ret) { + break; + } - // Check for timeout waiting for ACK to clear - if (!ret) { - break; - } + // Wait for ACK to clear + ret = WaitSignal(PIN_ACK, OFF); - // Advance the buffer pointer to receive the next byte - buf++; - } - } else { - // Get phase - DWORD phase = Acquire() & GPIO_MCI; + // Check for timeout waiting for ACK to clear + if (!ret) { + break; + } - for (i = 0; i < count; i++) { - // Wait for the REQ signal to be asserted - bool ret = WaitSignal(PIN_REQ, ON); + // Advance the buffer pointer to receive the next byte + buf++; + } + } else { + // Get phase + uint32_t phase = Acquire() & GPIO_MCI; - // Check for timeout waiting for REQ signal - if (!ret) { - break; - } + for (i = 0; i < count; i++) { + // Wait for the REQ signal to be asserted + bool ret = WaitSignal(PIN_REQ, ON); - // Phase error - if ((signals & GPIO_MCI) != phase) { - break; - } + // Check for timeout waiting for REQ signal + if (!ret) { + break; + } - // Wait until the signal line stabilizes - SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); + // Phase error + if ((signals & GPIO_MCI) != phase) { + break; + } - // Get data - *buf = GetDAT(); + // Wait until the signal line stabilizes + SysTimer::SleepNsec(SCSI_DELAY_BUS_SETTLE_DELAY_NS); - // Assert the ACK signal - SetSignal(PIN_ACK, ON); + // Get data + *buf = GetDAT(); - // Wait for REQ to clear - ret = WaitSignal(PIN_REQ, OFF); + // Assert the ACK signal + SetSignal(PIN_ACK, ON); - // Clear the ACK signal - SetSignal(PIN_ACK, OFF); + // Wait for REQ to clear + ret = WaitSignal(PIN_REQ, OFF); - // Check for timeout waiting for REQ to clear - if (!ret) { - break; - } + // Clear the ACK signal + SetSignal(PIN_ACK, OFF); - // Phase error - if ((signals & GPIO_MCI) != phase) { - break; - } + // Check for timeout waiting for REQ to clear + if (!ret) { + break; + } - // Advance the buffer pointer to receive the next byte - buf++; - } - } + // Phase error + if ((signals & GPIO_MCI) != phase) { + break; + } - // Re-enable IRQ - EnableIRQ(); + // Advance the buffer pointer to receive the next byte + buf++; + } + } - // Return the number of bytes received - return i; + // Re-enable IRQ + EnableIRQ(); + + // Return the number of bytes received + return i; } //--------------------------------------------------------------------------- @@ -904,108 +659,112 @@ int GPIOBUS::ReceiveHandShake(BYTE *buf, int count) //--------------------------------------------------------------------------- int GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes) { - int i; + GPIO_FUNCTION_TRACE - // Disable IRQs - DisableIRQ(); + int i; - if (actmode == mode_e::TARGET) { - for (i = 0; i < count; i++) { - if(i==delay_after_bytes){ - LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes) - SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US); - } + // Disable IRQs + DisableIRQ(); - // Set the DATA signals - SetDAT(*buf); + if (actmode == mode_e::TARGET) { + for (i = 0; i < count; i++) { + if (i == delay_after_bytes) { + LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, + (int)delay_after_bytes) + SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US); + } - // Wait for ACK to clear - bool ret = WaitSignal(PIN_ACK, OFF); + // Set the DATA signals + SetDAT(*buf); - // Check for timeout waiting for ACK to clear - if (!ret) { - break; - } + // Wait for ACK to clear + bool ret = WaitSignal(PIN_ACK, OFF); - // Already waiting for ACK to clear + // Check for timeout waiting for ACK to clear + if (!ret) { + break; + } - // Assert the REQ signal - SetSignal(PIN_REQ, ON); + // Already waiting for ACK to clear - // Wait for ACK - ret = WaitSignal(PIN_ACK, ON); + // Assert the REQ signal + SetSignal(PIN_REQ, ON); - // Clear REQ signal - SetSignal(PIN_REQ, OFF); + // Wait for ACK + ret = WaitSignal(PIN_ACK, ON); - // Check for timeout waiting for ACK to clear - if (!ret) { - break; - } + // Clear REQ signal + SetSignal(PIN_REQ, OFF); - // Advance the data buffer pointer to receive the next byte - buf++; - } + // Check for timeout waiting for ACK to clear + if (!ret) { + break; + } - // Wait for ACK to clear - WaitSignal(PIN_ACK, OFF); - } else { - // Get Phase - DWORD phase = Acquire() & GPIO_MCI; + // Advance the data buffer pointer to receive the next byte + buf++; + } - for (i = 0; i < count; i++) { - if(i==delay_after_bytes){ - LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, (int)delay_after_bytes) - SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US); - } + // Wait for ACK to clear + WaitSignal(PIN_ACK, OFF); + } else { + // Get Phase + uint32_t phase = Acquire() & GPIO_MCI; - // Set the DATA signals - SetDAT(*buf); + for (i = 0; i < count; i++) { + if (i == delay_after_bytes) { + LOGTRACE("%s DELAYING for %dus after %d bytes", __PRETTY_FUNCTION__, SCSI_DELAY_SEND_DATA_DAYNAPORT_US, + (int)delay_after_bytes) + SysTimer::SleepUsec(SCSI_DELAY_SEND_DATA_DAYNAPORT_US); + } - // Wait for REQ to be asserted - bool ret = WaitSignal(PIN_REQ, ON); + // Set the DATA signals + SetDAT(*buf); - // Check for timeout waiting for REQ to be asserted - if (!ret) { - break; - } + // Wait for REQ to be asserted + bool ret = WaitSignal(PIN_REQ, ON); - // Phase error - if ((signals & GPIO_MCI) != phase) { - break; - } + // Check for timeout waiting for REQ to be asserted + if (!ret) { + break; + } - // Already waiting for REQ assertion + // Phase error + if ((signals & GPIO_MCI) != phase) { + break; + } - // Assert the ACK signal - SetSignal(PIN_ACK, ON); + // Already waiting for REQ assertion - // Wait for REQ to clear - ret = WaitSignal(PIN_REQ, OFF); + // Assert the ACK signal + SetSignal(PIN_ACK, ON); - // Clear the ACK signal - SetSignal(PIN_ACK, OFF); + // Wait for REQ to clear + ret = WaitSignal(PIN_REQ, OFF); - // Check for timeout waiting for REQ to clear - if (!ret) { - break; - } + // Clear the ACK signal + SetSignal(PIN_ACK, OFF); - // Phase error - if ((signals & GPIO_MCI) != phase) { - break; - } + // Check for timeout waiting for REQ to clear + if (!ret) { + break; + } - // Advance the data buffer pointer to receive the next byte - buf++; - } - } + // Phase error + if ((signals & GPIO_MCI) != phase) { + break; + } - // Re-enable IRQ - EnableIRQ(); + // Advance the data buffer pointer to receive the next byte + buf++; + } + } - // Return number of transmissions - return i; + // Re-enable IRQ + EnableIRQ(); + + // Return number of transmissions + return i; } #ifdef USE_SEL_EVENT_ENABLE @@ -1016,19 +775,22 @@ int GPIOBUS::SendHandShake(BYTE *buf, int count, int delay_after_bytes) //--------------------------------------------------------------------------- bool GPIOBUS::PollSelectEvent() { - errno = 0; + GPIO_FUNCTION_TRACE + errno = 0; - if (epoll_event epev; epoll_wait(epfd, &epev, 1, -1) <= 0) { - LOGWARN("%s epoll_wait failed", __PRETTY_FUNCTION__) - return false; - } - - if (gpioevent_data gpev; read(selevreq.fd, &gpev, sizeof(gpev)) < 0) { - LOGWARN("%s read failed", __PRETTY_FUNCTION__) + if (epoll_event epev; epoll_wait(epfd, &epev, 1, -1) <= 0) { + LOGWARN("%s epoll_wait failed", __PRETTY_FUNCTION__) + LOGWARN("[%08X] %s", errno, strerror(errno)) return false; - } + } - return true; + if (gpioevent_data gpev; read(selevreq.fd, &gpev, sizeof(gpev)) < 0) { + LOGWARN("%s read failed", __PRETTY_FUNCTION__) + LOGWARN("[%08X] %s", errno, strerror(errno)) + return false; + } + + return true; } //--------------------------------------------------------------------------- @@ -1038,21 +800,18 @@ bool GPIOBUS::PollSelectEvent() //--------------------------------------------------------------------------- void GPIOBUS::ClearSelectEvent() { + GPIO_FUNCTION_TRACE } -#endif // USE_SEL_EVENT_ENABLE +#endif // USE_SEL_EVENT_ENABLE //--------------------------------------------------------------------------- // // Signal table // //--------------------------------------------------------------------------- -const array GPIOBUS::SignalTable = { - PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, - PIN_DT4, PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP, - PIN_SEL,PIN_ATN, PIN_RST, PIN_ACK, - PIN_BSY, PIN_MSG, PIN_CD, PIN_IO, PIN_REQ, - -1 -}; +const array GPIOBUS::SignalTable = {PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, PIN_DT5, PIN_DT6, + PIN_DT7, PIN_DP, PIN_SEL, PIN_ATN, PIN_RST, PIN_ACK, PIN_BSY, + PIN_MSG, PIN_CD, PIN_IO, PIN_REQ, -1}; //--------------------------------------------------------------------------- // @@ -1061,170 +820,92 @@ const array GPIOBUS::SignalTable = { //--------------------------------------------------------------------------- void GPIOBUS::MakeTable(void) { - const array pintbl = { - PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, - PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP - }; + GPIO_FUNCTION_TRACE - array tblParity; + const array pintbl = {PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP}; - // Create parity table - for (uint32_t i = 0; i < 0x100; i++) { - uint32_t bits = i; - uint32_t parity = 0; - for (int j = 0; j < 8; j++) { - parity ^= bits & 1; - bits >>= 1; - } - parity = ~parity; - tblParity[i] = parity & 1; - } + array tblParity; + + // Create parity table + for (uint32_t i = 0; i < 0x100; i++) { + uint32_t bits = i; + uint32_t parity = 0; + for (int j = 0; j < 8; j++) { + parity ^= bits & 1; + bits >>= 1; + } + parity = ~parity; + tblParity[i] = parity & 1; + } #if SIGNAL_CONTROL_MODE == 0 - // Mask and setting data generation - for (auto& tbl : tblDatMsk) { - tbl.fill(-1); - } - for (auto& tbl : tblDatSet) { - tbl.fill(0); - } + // Mask and setting data generation + for (auto &tbl : tblDatMsk) { + tbl.fill(-1); + } + for (auto &tbl : tblDatSet) { + tbl.fill(0); + } - for (uint32_t i = 0; i < 0x100; i++) { - // Bit string for inspection - uint32_t bits = i; + for (uint32_t i = 0; i < 0x100; i++) { + // Bit string for inspection + uint32_t bits = i; - // Get parity - if (tblParity[i]) { - bits |= (1 << 8); - } + // Get parity + if (tblParity[i]) { + bits |= (1 << 8); + } - // Bit check - for (int j = 0; j < 9; j++) { - // Index and shift amount calculation - int index = pintbl[j] / 10; - int shift = (pintbl[j] % 10) * 3; + // Bit check + for (int j = 0; j < 9; j++) { + // Index and shift amount calculation + int index = pintbl[j] / 10; + int shift = (pintbl[j] % 10) * 3; - // Mask data - tblDatMsk[index][i] &= ~(0x7 << shift); + // Mask data + tblDatMsk[index][i] &= ~(0x7 << shift); - // Setting data - if (bits & 1) { - tblDatSet[index][i] |= (1 << shift); - } + // Setting data + if (bits & 1) { + tblDatSet[index][i] |= (1 << shift); + } - bits >>= 1; - } - } + bits >>= 1; + } + } #else - for (uint32_t i = 0; i < 0x100; i++) { - // Bit string for inspection - uint32_t bits = i; + for (uint32_t i = 0; i < 0x100; i++) { + // Bit string for inspection + uint32_t bits = i; - // Get parity - if (tblParity[i]) { - bits |= (1 << 8); - } + // Get parity + if (tblParity[i]) { + bits |= (1 << 8); + } #if SIGNAL_CONTROL_MODE == 1 - // Negative logic is inverted - bits = ~bits; + // Negative logic is inverted + bits = ~bits; #endif - // Create GPIO register information - uint32_t gpclr = 0; - uint32_t gpset = 0; - for (int j = 0; j < 9; j++) { - if (bits & 1) { - gpset |= (1 << pintbl[j]); - } else { - gpclr |= (1 << pintbl[j]); - } - bits >>= 1; - } + // Create GPIO register information + uint32_t gpclr = 0; + uint32_t gpset = 0; + for (int j = 0; j < 9; j++) { + if (bits & 1) { + gpset |= (1 << pintbl[j]); + } else { + gpclr |= (1 << pintbl[j]); + } + bits >>= 1; + } - tblDatMsk[i] = gpclr; - tblDatSet[i] = gpset; - } + tblDatMsk[i] = gpclr; + tblDatSet[i] = gpset; + } #endif } -//--------------------------------------------------------------------------- -// -// Control signal setting -// -//--------------------------------------------------------------------------- -void GPIOBUS::SetControl(int pin, bool ast) -{ - PinSetSignal(pin, ast); -} - -//--------------------------------------------------------------------------- -// -// Input/output mode setting -// -//--------------------------------------------------------------------------- -void GPIOBUS::SetMode(int pin, int mode) -{ -#if SIGNAL_CONTROL_MODE == 0 - if (mode == OUT) { - return; - } -#endif // SIGNAL_CONTROL_MODE - - int index = pin / 10; - int shift = (pin % 10) * 3; - DWORD data = gpfsel[index]; - data &= ~(0x7 << shift); - if (mode == OUT) { - data |= (1 << shift); - } - gpio[index] = data; - gpfsel[index] = data; -} - -//--------------------------------------------------------------------------- -// -// Get input signal value -// -//--------------------------------------------------------------------------- -bool GPIOBUS::GetSignal(int pin) const -{ - return (signals >> pin) & 1; -} - -//--------------------------------------------------------------------------- -// -// Set output signal value -// -//--------------------------------------------------------------------------- -void GPIOBUS::SetSignal(int pin, bool ast) -{ -#if SIGNAL_CONTROL_MODE == 0 - int index = pin / 10; - int shift = (pin % 10) * 3; - DWORD data = gpfsel[index]; - if (ast) { - data |= (1 << shift); - } else { - data &= ~(0x7 << shift); - } - gpio[index] = data; - gpfsel[index] = data; -#elif SIGNAL_CONTROL_MODE == 1 - if (ast) { - gpio[GPIO_CLR_0] = 0x1 << pin; - } else { - gpio[GPIO_SET_0] = 0x1 << pin; - } -#elif SIGNAL_CONTROL_MODE == 2 - if (ast) { - gpio[GPIO_SET_0] = 0x1 << pin; - } else { - gpio[GPIO_CLR_0] = 0x1 << pin; - } -#endif // SIGNAL_CONTROL_MODE -} - //--------------------------------------------------------------------------- // // Wait for signal change @@ -1232,186 +913,59 @@ void GPIOBUS::SetSignal(int pin, bool ast) //--------------------------------------------------------------------------- bool GPIOBUS::WaitSignal(int pin, int ast) { - // Get current time - uint32_t now = SysTimer::GetTimerLow(); + GPIO_FUNCTION_TRACE - // Calculate timeout (3000ms) - uint32_t timeout = 3000 * 1000; + // Get current time + uint32_t now = SysTimer::GetTimerLow(); - // end immediately if the signal has changed - do { - // Immediately upon receiving a reset - Acquire(); - if (GetRST()) { - return false; - } + // Calculate timeout (3000ms) + uint32_t timeout = 3000 * 1000; - // Check for the signal edge + // end immediately if the signal has changed + do { + // Immediately upon receiving a reset + Acquire(); + if (GetRST()) { + return false; + } + + // Check for the signal edge if (((signals >> pin) ^ ~ast) & 1) { - return true; - } - } while ((SysTimer::GetTimerLow() - now) < timeout); + return true; + } + } while ((SysTimer::GetTimerLow() - now) < timeout); - // We timed out waiting for the signal - return false; + // We timed out waiting for the signal + return false; } -void GPIOBUS::DisableIRQ() -{ -#ifdef __linux__ - if (rpitype == 4) { - // RPI4 is disabled by GICC - giccpmr = gicc[GICC_PMR]; - gicc[GICC_PMR] = 0; - } else if (rpitype == 2) { - // RPI2,3 disable core timer IRQ - tintcore = sched_getcpu() + QA7_CORE0_TINTC; - tintctl = qa7regs[tintcore]; - qa7regs[tintcore] = 0; - } else { - // Stop system timer interrupt with interrupt controller - irptenb = irpctl[IRPT_ENB_IRQ_1]; - irpctl[IRPT_DIS_IRQ_1] = irptenb & 0xf; - } -#else - (void)0; -#endif -} - -void GPIOBUS::EnableIRQ() -{ - if (rpitype == 4) { - // RPI4 enables interrupts via the GICC - gicc[GICC_PMR] = giccpmr; - } else if (rpitype == 2) { - // RPI2,3 re-enable core timer IRQ - qa7regs[tintcore] = tintctl; - } else { - // Restart the system timer interrupt with the interrupt controller - irpctl[IRPT_ENB_IRQ_1] = irptenb & 0xf; - } -} - -//--------------------------------------------------------------------------- -// -// Pin direction setting (input/output) -// -//--------------------------------------------------------------------------- -void GPIOBUS::PinConfig(int pin, int mode) -{ - // Check for invalid pin - if (pin < 0) { - return; - } - - int index = pin / 10; - DWORD mask = ~(0x7 << ((pin % 10) * 3)); - gpio[index] = (gpio[index] & mask) | ((mode & 0x7) << ((pin % 10) * 3)); -} - -//--------------------------------------------------------------------------- -// -// Pin pull-up/pull-down setting -// -//--------------------------------------------------------------------------- -void GPIOBUS::PullConfig(int pin, int mode) -{ - DWORD pull; - - // Check for invalid pin - if (pin < 0) { - return; - } - - if (rpitype == 4) { - switch (mode) { - case GPIO_PULLNONE: - pull = 0; - break; - case GPIO_PULLUP: - pull = 1; - break; - case GPIO_PULLDOWN: - pull = 2; - break; - default: - return; - } - - pin &= 0x1f; - int shift = (pin & 0xf) << 1; - DWORD bits = gpio[GPIO_PUPPDN0 + (pin >> 4)]; - bits &= ~(3 << shift); - bits |= (pull << shift); - gpio[GPIO_PUPPDN0 + (pin >> 4)] = bits; - } else { - pin &= 0x1f; - gpio[GPIO_PUD] = mode & 0x3; - SysTimer::SleepUsec(2); - gpio[GPIO_CLK_0] = 0x1 << pin; - SysTimer::SleepUsec(2); - gpio[GPIO_PUD] = 0; - gpio[GPIO_CLK_0] = 0; - } -} - -//--------------------------------------------------------------------------- -// -// Set output pin -// -//--------------------------------------------------------------------------- -void GPIOBUS::PinSetSignal(int pin, bool ast) -{ - // Check for invalid pin - if (pin < 0) { - return; - } - - if (ast) { - gpio[GPIO_SET_0] = 0x1 << pin; - } else { - gpio[GPIO_CLR_0] = 0x1 << pin; - } -} - -//--------------------------------------------------------------------------- -// -// Set the signal drive strength -// -//--------------------------------------------------------------------------- -void GPIOBUS::DrvConfig(DWORD drive) -{ - DWORD data = pads[PAD_0_27]; - pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000; -} - - //--------------------------------------------------------------------------- // // Generic Phase Acquisition (Doesn't read GPIO) // //--------------------------------------------------------------------------- -BUS::phase_t GPIOBUS::GetPhaseRaw(DWORD raw_data) +BUS::phase_t GPIOBUS::GetPhaseRaw(uint32_t raw_data) { - // Selection Phase - if (GetPinRaw(raw_data, PIN_SEL)) { - if(GetPinRaw(raw_data, PIN_IO)) { - return BUS::phase_t::reselection; - } else{ - return BUS::phase_t::selection; - } - } + GPIO_FUNCTION_TRACE + // Selection Phase + if (GetPinRaw(raw_data, PIN_SEL)) { + if (GetPinRaw(raw_data, PIN_IO)) { + return BUS::phase_t::reselection; + } else { + return BUS::phase_t::selection; + } + } - // Bus busy phase - if (!GetPinRaw(raw_data, PIN_BSY)) { - return BUS::phase_t::busfree; - } + // Bus busy phase + if (!GetPinRaw(raw_data, PIN_BSY)) { + return BUS::phase_t::busfree; + } - // Get target phase from bus signal line - int mci = GetPinRaw(raw_data, PIN_MSG) ? 0x04 : 0x00; - mci |= GetPinRaw(raw_data, PIN_CD) ? 0x02 : 0x00; - mci |= GetPinRaw(raw_data, PIN_IO) ? 0x01 : 0x00; - return GetPhase(mci); + // Get target phase from bus signal line + int mci = GetPinRaw(raw_data, PIN_MSG) ? 0x04 : 0x00; + mci |= GetPinRaw(raw_data, PIN_CD) ? 0x02 : 0x00; + mci |= GetPinRaw(raw_data, PIN_IO) ? 0x01 : 0x00; + return GetPhase(mci); } //--------------------------------------------------------------------------- @@ -1419,17 +973,17 @@ BUS::phase_t GPIOBUS::GetPhaseRaw(DWORD raw_data) // Get the number of bytes for a command // //--------------------------------------------------------------------------- -int GPIOBUS::GetCommandByteCount(BYTE opcode) { - if (opcode == 0x88 || opcode == 0x8A || opcode == 0x8F || opcode == 0x91 || opcode == 0x9E || opcode == 0x9F) { - return 16; - } - else if (opcode == 0xA0) { - return 12; - } - else if (opcode == 0x05 || (opcode >= 0x20 && opcode <= 0x7D)) { - return 10; - } else { - return 6; - } -} +int GPIOBUS::GetCommandByteCount(BYTE opcode) +{ + GPIO_FUNCTION_TRACE + if (opcode == 0x88 || opcode == 0x8A || opcode == 0x8F || opcode == 0x91 || opcode == 0x9E || opcode == 0x9F) { + return 16; + } else if (opcode == 0xA0) { + return 12; + } else if (opcode == 0x05 || (opcode >= 0x20 && opcode <= 0x7D)) { + return 10; + } else { + return 6; + } +} diff --git a/src/raspberrypi/hal/gpiobus.h b/src/raspberrypi/hal/gpiobus.h index 9dfb1bbf..39afc819 100644 --- a/src/raspberrypi/hal/gpiobus.h +++ b/src/raspberrypi/hal/gpiobus.h @@ -41,7 +41,13 @@ #error Invalid connection type or none specified #endif -using namespace std; //NOSONAR Not relevant for rascsi +#ifdef ENABLE_GPIO_TRACE +#define GPIO_FUNCTION_TRACE LOGTRACE("%s", __PRETTY_FUNCTION__) +#else +#define GPIO_FUNCTION_TRACE +#endif + +using namespace std; // NOSONAR Not relevant for rascsi //--------------------------------------------------------------------------- // @@ -117,399 +123,318 @@ using namespace std; //NOSONAR Not relevant for rascsi // //--------------------------------------------------------------------------- -#define ALL_SCSI_PINS \ - ((1< gpfsel; // GPFSEL0-4 backup values - - uint32_t signals = 0; // All bus signals + static int GetCommandByteCount(BYTE opcode); #ifdef USE_SEL_EVENT_ENABLE - struct gpioevent_request selevreq = {}; // SEL signal event request + // SEL signal interrupt + bool PollSelectEvent(); + // SEL signal event polling + void ClearSelectEvent(); + // Clear SEL signal event +#endif // USE_SEL_EVENT_ENABLE - int epfd; // epoll file descriptor -#endif // USE_SEL_EVENT_ENABLE + protected: + // SCSI I/O signal control + virtual void MakeTable() = 0; + // Create work data + virtual void SetControl(int pin, bool ast) = 0; + // Set Control Signal + virtual void SetMode(int pin, int mode) = 0; + // Set SCSI I/O mode + bool GetSignal(int pin) const override = 0; + // Set Control Signal + void SetSignal(int pin, bool ast) override = 0; + // Set SCSI I/O mode + virtual bool WaitSignal(int pin, int ast) = 0; + // Wait for a signal to change + // Interrupt control + virtual void DisableIRQ() = 0; + // IRQ Disabled + virtual void EnableIRQ() = 0; + // IRQ Enabled -#if SIGNAL_CONTROL_MODE == 0 - array, 3> tblDatMsk; // Data mask table + // GPIO pin functionality settings + virtual void PinConfig(int pin, int mode) = 0; + // GPIO pin direction setting + virtual void PullConfig(int pin, int mode) = 0; + // GPIO pin pull up/down resistor setting + virtual void PinSetSignal(int pin, bool ast) = 0; + // Set GPIO output signal + virtual void DrvConfig(uint32_t drive) = 0; + // Set GPIO drive strength - array, 3> tblDatSet; // Data setting table -#else - array tblDatMsk = {}; // Data mask table + mode_e actmode = mode_e::TARGET; // Operation mode - array tblDatSet = {}; // Table setting table +#if !defined(__x86_64__) && !defined(__X86__) + uint32_t baseaddr = 0; // Base address #endif - static const array SignalTable; // signal table -}; + static const array SignalTable; // signal table +#ifdef USE_SEL_EVENT_ENABLE + struct gpioevent_request selevreq = {}; // SEL signal event request + + int epfd; // epoll file descriptor +#endif // USE_SEL_EVENT_ENABLE + + private: + int rpitype = 0; // Type of Raspberry Pi + + volatile uint32_t *gpio = nullptr; // GPIO register + + volatile uint32_t *pads = nullptr; // PADS register + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *level = nullptr; // GPIO input level +#endif + + volatile uint32_t *irpctl = nullptr; // Interrupt control register + + volatile uint32_t irptenb; // Interrupt enabled state + + volatile uint32_t *qa7regs = nullptr; // QA7 register + + volatile int tintcore; // Interupt control target CPU. + + volatile uint32_t tintctl; // Interupt control + + volatile uint32_t giccpmr; // GICC priority setting + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register +#endif + + volatile uint32_t *gicc = nullptr; // GIC CPU interface register + + array gpfsel; // GPFSEL0-4 backup values + + uint32_t signals = 0; // All bus signals + +#if SIGNAL_CONTROL_MODE == 0 + array, 3> tblDatMsk; // Data mask table + + array, 3> tblDatSet; // Data setting table +#else + array tblDatMsk = {}; // Data mask table + + array tblDatSet = {}; // Table setting table +#endif +}; diff --git a/src/raspberrypi/hal/gpiobus_aibom.h b/src/raspberrypi/hal/gpiobus_aibom.h index 01f1f9e6..6fbb0425 100644 --- a/src/raspberrypi/hal/gpiobus_aibom.h +++ b/src/raspberrypi/hal/gpiobus_aibom.h @@ -16,41 +16,41 @@ // RaSCSI Adapter Aibom version // -const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message +const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message // Select signal control mode -const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification +const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification // Control signal output logic -#define ACT_ON ON // ACTIVE SIGNAL ON -#define ENB_ON ON // ENABLE SIGNAL ON -#define IND_IN OFF // INITIATOR SIGNAL INPUT -#define TAD_IN OFF // TARGET SIGNAL INPUT -#define DTD_IN OFF // DATA SIGNAL INPUT +#define ACT_ON ON // ACTIVE SIGNAL ON +#define ENB_ON ON // ENABLE SIGNAL ON +#define IND_IN OFF // INITIATOR SIGNAL INPUT +#define TAD_IN OFF // TARGET SIGNAL INPUT +#define DTD_IN OFF // DATA SIGNAL INPUT // Control signal pin assignment (-1 means no control) -const static int PIN_ACT = 4; // ACTIVE -const static int PIN_ENB = 17; // ENABLE -const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION -const static int PIN_TAD = -1; // TARGET CTRL DIRECTION -const static int PIN_DTD = 18; // DATA DIRECTION +const static int PIN_ACT = 4; // ACTIVE +const static int PIN_ENB = 17; // ENABLE +const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION +const static int PIN_TAD = -1; // TARGET CTRL DIRECTION +const static int PIN_DTD = 18; // DATA DIRECTION // SCSI signal pin assignment -const static int PIN_DT0 = 6; // Data 0 -const static int PIN_DT1 = 12; // Data 1 -const static int PIN_DT2 = 13; // Data 2 -const static int PIN_DT3 = 16; // Data 3 -const static int PIN_DT4 = 19; // Data 4 -const static int PIN_DT5 = 20; // Data 5 -const static int PIN_DT6 = 26; // Data 6 -const static int PIN_DT7 = 21; // Data 7 -const static int PIN_DP = 5; // Data parity -const static int PIN_ATN = 22; // ATN -const static int PIN_RST = 25; // RST -const static int PIN_ACK = 10; // ACK -const static int PIN_REQ = 7; // REQ -const static int PIN_MSG = 9; // MSG -const static int PIN_CD = 11; // CD -const static int PIN_IO = 23; // IO -const static int PIN_BSY = 24; // BSY -const static int PIN_SEL = 8; // SEL +const static int PIN_DT0 = 6; // Data 0 +const static int PIN_DT1 = 12; // Data 1 +const static int PIN_DT2 = 13; // Data 2 +const static int PIN_DT3 = 16; // Data 3 +const static int PIN_DT4 = 19; // Data 4 +const static int PIN_DT5 = 20; // Data 5 +const static int PIN_DT6 = 26; // Data 6 +const static int PIN_DT7 = 21; // Data 7 +const static int PIN_DP = 5; // Data parity +const static int PIN_ATN = 22; // ATN +const static int PIN_RST = 25; // RST +const static int PIN_ACK = 10; // ACK +const static int PIN_REQ = 7; // REQ +const static int PIN_MSG = 9; // MSG +const static int PIN_CD = 11; // CD +const static int PIN_IO = 23; // IO +const static int PIN_BSY = 24; // BSY +const static int PIN_SEL = 8; // SEL diff --git a/src/raspberrypi/hal/gpiobus_allwinner.cpp b/src/raspberrypi/hal/gpiobus_allwinner.cpp new file mode 100644 index 00000000..272b3fe5 --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_allwinner.cpp @@ -0,0 +1,120 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// +// [ GPIO-SCSI bus ] +// +//--------------------------------------------------------------------------- + +#include "hal/gpiobus_allwinner.h" +#include "hal/gpiobus.h" +#include "log.h" + +extern int wiringPiMode; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +bool GPIOBUS_Allwinner::Init(mode_e mode) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) + return false; +} + +void GPIOBUS_Allwinner::Cleanup() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::Reset(){LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)} + +BYTE GPIOBUS_Allwinner::GetDAT() +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) + return 0; +} + +void GPIOBUS_Allwinner::SetDAT(BYTE dat) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::MakeTable(void) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::SetControl(int pin, bool ast) +{ + GPIOBUS_Allwinner::SetSignal(pin, ast); +} + +void GPIOBUS_Allwinner::SetMode(int pin, int mode) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +bool GPIOBUS_Allwinner::GetSignal(int pin) const +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) + return false; + // return (digitalRead(pin) != 0); +} + +void GPIOBUS_Allwinner::SetSignal(int pin, bool ast) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +bool GPIOBUS_Allwinner::WaitSignal(int pin, int ast) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) + return false; +} + +void GPIOBUS_Allwinner::DisableIRQ() +{ + LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::EnableIRQ() +{ + LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::PinConfig(int pin, int mode) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::PullConfig(int pin, int mode) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::PinSetSignal(int pin, bool ast) +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) +} + +void GPIOBUS_Allwinner::DrvConfig(DWORD drive) +{ + (void)drive; + LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__) +} + +uint32_t GPIOBUS_Allwinner::Acquire() +{ + LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__) + // Only used for development/debugging purposes. Isn't really applicable + // to any real-world RaSCSI application + return 0; +} + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/src/raspberrypi/hal/gpiobus_allwinner.h b/src/raspberrypi/hal/gpiobus_allwinner.h new file mode 100644 index 00000000..d02ae866 --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_allwinner.h @@ -0,0 +1,128 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// [ GPIO-SCSI bus ] +// +//--------------------------------------------------------------------------- + +#pragma once + +#include "config.h" +#include "hal/gpiobus.h" +#include "log.h" +#include "scsi.h" + +//--------------------------------------------------------------------------- +// +// Class definition +// +//--------------------------------------------------------------------------- +class GPIOBUS_Allwinner : public GPIOBUS +{ + public: + // Basic Functions + GPIOBUS_Allwinner() = default; + ~GPIOBUS_Allwinner() override = default; + // Destructor + bool Init(mode_e mode = mode_e::TARGET) override; + // Initialization + void Reset() override; + // Reset + void Cleanup() override; + // Cleanup + + //--------------------------------------------------------------------------- + // + // Bus signal acquisition + // + //--------------------------------------------------------------------------- + uint32_t Acquire() override; + + BYTE GetDAT() override; + // Get DAT signal + void SetDAT(BYTE dat) override; + // Set DAT signal + protected: + // SCSI I/O signal control + void MakeTable() override; + // Create work data + void SetControl(int pin, bool ast) override; + // Set Control Signal + void SetMode(int pin, int mode) override; + // Set SCSI I/O mode + bool GetSignal(int pin) const override; + // Get SCSI input signal value + void SetSignal(int pin, bool ast) override; + // Set SCSI output signal value + bool WaitSignal(int pin, int ast) override; + // Wait for a signal to change + // Interrupt control + void DisableIRQ() override; + // IRQ Disabled + void EnableIRQ() override; + // IRQ Enabled + + // GPIO pin functionality settings + void PinConfig(int pin, int mode) override; + // GPIO pin direction setting + void PullConfig(int pin, int mode) override; + // GPIO pin pull up/down resistor setting + void PinSetSignal(int pin, bool ast) override; + // Set GPIO output signal + void DrvConfig(DWORD drive) override; + // Set GPIO drive strength + +#if !defined(__x86_64__) && !defined(__X86__) + uint32_t baseaddr = 0; // Base address +#endif + + volatile uint32_t *gpio = nullptr; // GPIO register + + volatile uint32_t *pads = nullptr; // PADS register + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *level = nullptr; // GPIO input level +#endif + + volatile uint32_t *irpctl = nullptr; // Interrupt control register + + volatile uint32_t irptenb; // Interrupt enabled state + + volatile uint32_t *qa7regs = nullptr; // QA7 register + + volatile int tintcore; // Interupt control target CPU. + + volatile uint32_t tintctl; // Interupt control + + volatile uint32_t giccpmr; // GICC priority setting + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register +#endif + + volatile uint32_t *gicc = nullptr; // GIC CPU interface register + + array gpfsel; // GPFSEL0-4 backup values + + uint32_t signals = 0; // All bus signals + +#ifdef USE_SEL_EVENT_ENABLE + struct gpioevent_request selevreq = {}; // SEL signal event request + + int epfd; // epoll file descriptor +#endif // USE_SEL_EVENT_ENABLE + +#if SIGNAL_CONTROL_MODE == 0 + array, 3> tblDatMsk; // Data mask table + + array, 3> tblDatSet; // Data setting table +#else + array tblDatMsk = {}; // Data mask table + + array tblDatSet = {}; // Table setting table +#endif +}; diff --git a/src/raspberrypi/hal/gpiobus_factory.cpp b/src/raspberrypi/hal/gpiobus_factory.cpp new file mode 100644 index 00000000..6e0ae96d --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_factory.cpp @@ -0,0 +1,30 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Copyright (C) 2022 akuker +// [ GPIO bus factory ] +// +//--------------------------------------------------------------------------- + +#include + +#include "hal/gpiobus_allwinner.h" +#include "hal/gpiobus_factory.h" +#include "hal/gpiobus_raspberry.h" +#include "hal/sbc_version.h" +#include "log.h" + +using namespace std; + +unique_ptr GPIOBUS_Factory::Create() +{ + if (SBC_Version::IsBananaPi()) { + LOGTRACE("Creating GPIOBUS_Allwinner") + return make_unique(); + } else { + LOGTRACE("Creating GPIOBUS_Raspberry") + return make_unique(); + } +} diff --git a/src/raspberrypi/hal/gpiobus_factory.h b/src/raspberrypi/hal/gpiobus_factory.h new file mode 100644 index 00000000..cc0bac8a --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_factory.h @@ -0,0 +1,24 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// [ GPIO-SCSI bus ] +// +//--------------------------------------------------------------------------- + +#pragma once + +#include + +#include "gpiobus.h" + +using namespace std; + +class GPIOBUS_Factory +{ + public: + static unique_ptr Create(); +}; diff --git a/src/raspberrypi/hal/gpiobus_fullspec.h b/src/raspberrypi/hal/gpiobus_fullspec.h index ee62c6d5..9f47eb07 100644 --- a/src/raspberrypi/hal/gpiobus_fullspec.h +++ b/src/raspberrypi/hal/gpiobus_fullspec.h @@ -16,41 +16,41 @@ // RaSCSI standard (SCSI logic, standard pin assignment) // -const std::string CONNECT_DESC = "FULLSPEC"; // Startup message +const std::string CONNECT_DESC = "FULLSPEC"; // Startup message // Select signal control mode -const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification +const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification // Control signal pin assignment (-1 means no control) -const static int PIN_ACT = 4; // ACTIVE -const static int PIN_ENB = 5; // ENABLE -const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION -const static int PIN_TAD = 7; // TARGET CTRL DIRECTION -const static int PIN_DTD = 8; // DATA DIRECTION +const static int PIN_ACT = 4; // ACTIVE +const static int PIN_ENB = 5; // ENABLE +const static int PIN_IND = 6; // INITIATOR CTRL DIRECTION +const static int PIN_TAD = 7; // TARGET CTRL DIRECTION +const static int PIN_DTD = 8; // DATA DIRECTION // Control signal output logic -#define ACT_ON ON // ACTIVE SIGNAL ON -#define ENB_ON ON // ENABLE SIGNAL ON -#define IND_IN OFF // INITIATOR SIGNAL INPUT -#define TAD_IN OFF // TARGET SIGNAL INPUT -#define DTD_IN ON // DATA SIGNAL INPUT +#define ACT_ON ON // ACTIVE SIGNAL ON +#define ENB_ON ON // ENABLE SIGNAL ON +#define IND_IN OFF // INITIATOR SIGNAL INPUT +#define TAD_IN OFF // TARGET SIGNAL INPUT +#define DTD_IN ON // DATA SIGNAL INPUT // SCSI signal pin assignment -const static int PIN_DT0 = 10; // Data 0 -const static int PIN_DT1 = 11; // Data 1 -const static int PIN_DT2 = 12; // Data 2 -const static int PIN_DT3 = 13; // Data 3 -const static int PIN_DT4 = 14; // Data 4 -const static int PIN_DT5 = 15; // Data 5 -const static int PIN_DT6 = 16; // Data 6 -const static int PIN_DT7 = 17; // Data 7 -const static int PIN_DP = 18; // Data parity -const static int PIN_ATN = 19; // ATN -const static int PIN_RST = 20; // RST -const static int PIN_ACK = 21; // ACK -const static int PIN_REQ = 22; // REQ -const static int PIN_MSG = 23; // MSG -const static int PIN_CD = 24; // CD -const static int PIN_IO = 25; // IO -const static int PIN_BSY = 26; // BSY -const static int PIN_SEL = 27; // SEL +const static int PIN_DT0 = 10; // Data 0 +const static int PIN_DT1 = 11; // Data 1 +const static int PIN_DT2 = 12; // Data 2 +const static int PIN_DT3 = 13; // Data 3 +const static int PIN_DT4 = 14; // Data 4 +const static int PIN_DT5 = 15; // Data 5 +const static int PIN_DT6 = 16; // Data 6 +const static int PIN_DT7 = 17; // Data 7 +const static int PIN_DP = 18; // Data parity +const static int PIN_ATN = 19; // ATN +const static int PIN_RST = 20; // RST +const static int PIN_ACK = 21; // ACK +const static int PIN_REQ = 22; // REQ +const static int PIN_MSG = 23; // MSG +const static int PIN_CD = 24; // CD +const static int PIN_IO = 25; // IO +const static int PIN_BSY = 26; // BSY +const static int PIN_SEL = 27; // SEL diff --git a/src/raspberrypi/hal/gpiobus_gamernium.h b/src/raspberrypi/hal/gpiobus_gamernium.h index bf295284..ca4e0d76 100644 --- a/src/raspberrypi/hal/gpiobus_gamernium.h +++ b/src/raspberrypi/hal/gpiobus_gamernium.h @@ -16,42 +16,41 @@ // RaSCSI Adapter GAMERnium.com version // -const std::string CONNECT_DESC = "GAMERnium.com version"; // Startup message +const std::string CONNECT_DESC = "GAMERnium.com version"; // Startup message // Select signal control mode -const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification +const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification // Control signal output logic -#define ACT_ON ON // ACTIVE SIGNAL ON -#define ENB_ON ON // ENABLE SIGNAL ON -#define IND_IN OFF // INITIATOR SIGNAL INPUT -#define TAD_IN OFF // TARGET SIGNAL INPUT -#define DTD_IN ON // DATA SIGNAL INPUT +#define ACT_ON ON // ACTIVE SIGNAL ON +#define ENB_ON ON // ENABLE SIGNAL ON +#define IND_IN OFF // INITIATOR SIGNAL INPUT +#define TAD_IN OFF // TARGET SIGNAL INPUT +#define DTD_IN ON // DATA SIGNAL INPUT // Control signal pin assignment (-1 means no control) -const static int PIN_ACT = 14; // ACTIVE -const static int PIN_ENB = 6; // ENABLE -const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION -const static int PIN_TAD = 8; // TARGET CTRL DIRECTION -const static int PIN_DTD = 5; // DATA DIRECTION +const static int PIN_ACT = 14; // ACTIVE +const static int PIN_ENB = 6; // ENABLE +const static int PIN_IND = 7; // INITIATOR CTRL DIRECTION +const static int PIN_TAD = 8; // TARGET CTRL DIRECTION +const static int PIN_DTD = 5; // DATA DIRECTION // SCSI signal pin assignment -const static int PIN_DT0 = 21; // Data 0 -const static int PIN_DT1 = 26; // Data 1 -const static int PIN_DT2 = 20; // Data 2 -const static int PIN_DT3 = 19; // Data 3 -const static int PIN_DT4 = 16; // Data 4 -const static int PIN_DT5 = 13; // Data 5 -const static int PIN_DT6 = 12; // Data 6 -const static int PIN_DT7 = 11; // Data 7 -const static int PIN_DP = 25; // Data parity -const static int PIN_ATN = 10; // ATN -const static int PIN_RST = 22; // RST -const static int PIN_ACK = 24; // ACK -const static int PIN_REQ = 15; // REQ -const static int PIN_MSG = 17; // MSG -const static int PIN_CD = 18; // CD -const static int PIN_IO = 4; // IO -const static int PIN_BSY = 27; // BSY -const static int PIN_SEL = 23; // SEL - +const static int PIN_DT0 = 21; // Data 0 +const static int PIN_DT1 = 26; // Data 1 +const static int PIN_DT2 = 20; // Data 2 +const static int PIN_DT3 = 19; // Data 3 +const static int PIN_DT4 = 16; // Data 4 +const static int PIN_DT5 = 13; // Data 5 +const static int PIN_DT6 = 12; // Data 6 +const static int PIN_DT7 = 11; // Data 7 +const static int PIN_DP = 25; // Data parity +const static int PIN_ATN = 10; // ATN +const static int PIN_RST = 22; // RST +const static int PIN_ACK = 24; // ACK +const static int PIN_REQ = 15; // REQ +const static int PIN_MSG = 17; // MSG +const static int PIN_CD = 18; // CD +const static int PIN_IO = 4; // IO +const static int PIN_BSY = 27; // BSY +const static int PIN_SEL = 23; // SEL diff --git a/src/raspberrypi/hal/gpiobus_raspberry.cpp b/src/raspberrypi/hal/gpiobus_raspberry.cpp new file mode 100644 index 00000000..d0d324eb --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_raspberry.cpp @@ -0,0 +1,857 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// +// [ GPIO-SCSI bus ] +// +//--------------------------------------------------------------------------- + +#include + +#include "config.h" +#include "hal/gpiobus.h" +#include "hal/gpiobus_raspberry.h" +#include "hal/systimer.h" +#include "log.h" +#include "os.h" +#include +#include +#include +#include +#include + +#ifdef __linux__ +//--------------------------------------------------------------------------- +// +// imported from bcm_host.c +// +//--------------------------------------------------------------------------- +static uint32_t get_dt_ranges(const char *filename, uint32_t offset) +{ + GPIO_FUNCTION_TRACE + uint32_t address = ~0; + if (FILE *fp = fopen(filename, "rb"); fp) { + fseek(fp, offset, SEEK_SET); + if (array buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) { + address = (int)buf[0] << 24 | (int)buf[1] << 16 | (int)buf[2] << 8 | (int)buf[3] << 0; + } + fclose(fp); + } + return address; +} + +uint32_t bcm_host_get_peripheral_address() +{ + GPIO_FUNCTION_TRACE + uint32_t address = get_dt_ranges("/proc/device-tree/soc/ranges", 4); + if (address == 0) { + address = get_dt_ranges("/proc/device-tree/soc/ranges", 8); + } + address = (address == (uint32_t)~0) ? 0x20000000 : address; + return address; +} +#endif // __linux__ + +#ifdef __NetBSD__ +// Assume the Raspberry Pi series and estimate the address from CPU +uint32_t bcm_host_get_peripheral_address() +{ + GPIO_FUNCTION_TRACE + array buf; + size_t len = buf.size(); + uint32_t address; + + if (sysctlbyname("hw.model", buf.data(), &len, NULL, 0) || strstr(buf, "ARM1176JZ-S") != buf.data()) { + // Failed to get CPU model || Not BCM2835 + // use the address of BCM283[67] + address = 0x3f000000; + } else { + // Use BCM2835 address + address = 0x20000000; + } + LOGDEBUG("Peripheral address : 0x%lx\n", address); + return address; +} +#endif // __NetBSD__ + +bool GPIOBUS_Raspberry::Init(mode_e mode) +{ + GPIO_FUNCTION_TRACE + GPIOBUS::Init(mode); + +#if defined(__x86_64__) || defined(__X86__) + + // When we're running on x86, there is no hardware to talk to, so just return. + return true; +#else +#ifdef USE_SEL_EVENT_ENABLE + epoll_event ev = {}; +#endif + + // Get the base address + baseaddr = (uint32_t)bcm_host_get_peripheral_address(); + LOGTRACE("%s Base addr: %08X", __PRETTY_FUNCTION__, baseaddr); + + // Open /dev/mem + int fd = open("/dev/mem", O_RDWR | O_SYNC); + if (fd == -1) { + LOGERROR("Error: Unable to open /dev/mem. Are you running as root?") + return false; + } + + LOGTRACE("%s Mapping Memory....", __PRETTY_FUNCTION__); + + // Map peripheral region memory + void *map = mmap(NULL, 0x1000100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, baseaddr); + if (map == MAP_FAILED) { + LOGERROR("Error: Unable to map memory") + close(fd); + return false; + } + LOGTRACE("%s Done!", __PRETTY_FUNCTION__); + + // Determine the type of raspberry pi from the base address + if (baseaddr == 0xfe000000) { + rpitype = 4; + LOGINFO("%s I'm a pi 4", __PRETTY_FUNCTION__); + } else if (baseaddr == 0x3f000000) { + rpitype = 2; + } else { + rpitype = 1; + } + + // GPIO + gpio = (uint32_t *)map; + gpio += GPIO_OFFSET / sizeof(uint32_t); + level = &gpio[GPIO_LEV_0]; + + // PADS + pads = (uint32_t *)map; + pads += PADS_OFFSET / sizeof(uint32_t); + + // // System timer + // SysTimer::Init( + // (uint32_t *)map + SYST_OFFSET / sizeof(uint32_t), + // (uint32_t *)map + ARMT_OFFSET / sizeof(uint32_t)); + SysTimer::Init(); + + // Interrupt controller + irpctl = (uint32_t *)map; + irpctl += IRPT_OFFSET / sizeof(uint32_t); + + // Quad-A7 control + qa7regs = (uint32_t *)map; + qa7regs += QA7_OFFSET / sizeof(uint32_t); + + LOGTRACE("%s Mapping GIC Memory....", __PRETTY_FUNCTION__); + // Map GIC memory + if (rpitype == 4) { + map = mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ARM_GICD_BASE); + if (map == MAP_FAILED) { + close(fd); + return false; + } + gicd = (uint32_t *)map; + gicc = (uint32_t *)map; + gicc += (ARM_GICC_BASE - ARM_GICD_BASE) / sizeof(uint32_t); + } else { + gicd = NULL; + gicc = NULL; + } + close(fd); + + LOGTRACE("%s Set Drive Strength", __PRETTY_FUNCTION__); + // Set Drive Strength to 16mA + DrvConfig(7); + + // Set pull up/pull down + LOGTRACE("%s Set pull up/down....", __PRETTY_FUNCTION__); + +#if SIGNAL_CONTROL_MODE == 0 + LOGTRACE("%s GPIO_PULLNONE", __PRETTY_FUNCTION__); + int pullmode = GPIO_PULLNONE; +#elif SIGNAL_CONTROL_MODE == 1 + LOGTRACE("%s GPIO_PULLUP", __PRETTY_FUNCTION__); + int pullmode = GPIO_PULLUP; +#else + LOGTRACE("%s GPIO_PULLDOWN", __PRETTY_FUNCTION__); + int pullmode = GPIO_PULLDOWN; +#endif + + // Initialize all signals + LOGTRACE("%s Initialize all signals....", __PRETTY_FUNCTION__); + + for (int i = 0; SignalTable[i] >= 0; i++) { + int j = SignalTable[i]; + PinSetSignal(j, OFF); + PinConfig(j, GPIO_INPUT); + PullConfig(j, pullmode); + } + + // Set control signals + LOGTRACE("%s Set control signals....", __PRETTY_FUNCTION__); + PinSetSignal(PIN_ACT, OFF); + PinSetSignal(PIN_TAD, OFF); + PinSetSignal(PIN_IND, OFF); + PinSetSignal(PIN_DTD, OFF); + PinConfig(PIN_ACT, GPIO_OUTPUT); + PinConfig(PIN_TAD, GPIO_OUTPUT); + PinConfig(PIN_IND, GPIO_OUTPUT); + PinConfig(PIN_DTD, GPIO_OUTPUT); + + // Set the ENABLE signal + // This is used to show that the application is running + PinSetSignal(PIN_ENB, ENB_OFF); + PinConfig(PIN_ENB, GPIO_OUTPUT); + + // GPFSEL backup + LOGTRACE("%s GPFSEL backup....", __PRETTY_FUNCTION__); + + gpfsel[0] = gpio[GPIO_FSEL_0]; + gpfsel[1] = gpio[GPIO_FSEL_1]; + gpfsel[2] = gpio[GPIO_FSEL_2]; + gpfsel[3] = gpio[GPIO_FSEL_3]; + + // Initialize SEL signal interrupt +#ifdef USE_SEL_EVENT_ENABLE + // GPIO chip open + LOGTRACE("%s GPIO chip open", __PRETTY_FUNCTION__); + int gpio_fd = open("/dev/gpiochip0", 0); + if (gpio_fd == -1) { + LOGERROR("Unable to open /dev/gpiochip0. Is RaSCSI already running?") + return false; + } + + // Event request setting + LOGTRACE("%s Event request setting (pin sel: %d)", __PRETTY_FUNCTION__, PIN_SEL); + strcpy(selevreq.consumer_label, "RaSCSI"); + selevreq.lineoffset = PIN_SEL; + selevreq.handleflags = GPIOHANDLE_REQUEST_INPUT; +#if SIGNAL_CONTROL_MODE < 2 + selevreq.eventflags = GPIOEVENT_REQUEST_FALLING_EDGE; + LOGTRACE("%s eventflags = GPIOEVENT_REQUEST_FALLING_EDGE", __PRETTY_FUNCTION__); +#else + selevreq.eventflags = GPIOEVENT_REQUEST_RISING_EDGE; + LOGTRACE("%s eventflags = GPIOEVENT_REQUEST_RISING_EDGE", __PRETTY_FUNCTION__); +#endif // SIGNAL_CONTROL_MODE + + // Get event request + if (ioctl(gpio_fd, GPIO_GET_LINEEVENT_IOCTL, &selevreq) == -1) { + LOGERROR("selevreq.fd = %d %08X", selevreq.fd, (unsigned int)selevreq.fd); + LOGERROR("Unable to register event request. Is RaSCSI already running?") + LOGERROR("[%08X] %s", errno, strerror(errno)); + close(gpio_fd); + return false; + } + + // Close GPIO chip file handle + LOGTRACE("%s Close GPIO chip file handle", __PRETTY_FUNCTION__); + close(gpio_fd); + + // epoll initialization + LOGTRACE("%s epoll initialization", __PRETTY_FUNCTION__); + epfd = epoll_create(1); + if (epfd == -1) { + LOGERROR("Unable to create the epoll event"); + return false; + } + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN | EPOLLPRI; + ev.data.fd = selevreq.fd; + epoll_ctl(epfd, EPOLL_CTL_ADD, selevreq.fd, &ev); +#else + // Edge detection setting +#if SIGNAL_CONTROL_MODE == 2 + gpio[GPIO_AREN_0] = 1 << PIN_SEL; +#else + gpio[GPIO_AFEN_0] = 1 << PIN_SEL; +#endif // SIGNAL_CONTROL_MODE + + // Clear event + gpio[GPIO_EDS_0] = 1 << PIN_SEL; + + // Register interrupt handler + setIrqFuncAddress(IrqHandler); + + // GPIO interrupt setting + if (rpitype == 4) { + // GIC Invalid + gicd[GICD_CTLR] = 0; + + // Route all interupts to core 0 + for (i = 0; i < 8; i++) { + gicd[GICD_ICENABLER0 + i] = 0xffffffff; + gicd[GICD_ICPENDR0 + i] = 0xffffffff; + gicd[GICD_ICACTIVER0 + i] = 0xffffffff; + } + for (i = 0; i < 64; i++) { + gicd[GICD_IPRIORITYR0 + i] = 0xa0a0a0a0; + gicd[GICD_ITARGETSR0 + i] = 0x01010101; + } + + // Set all interrupts as level triggers + for (i = 0; i < 16; i++) { + gicd[GICD_ICFGR0 + i] = 0; + } + + // GIC Invalid + gicd[GICD_CTLR] = 1; + + // Enable CPU interface for core 0 + gicc[GICC_PMR] = 0xf0; + gicc[GICC_CTLR] = 1; + + // Enable interrupts + gicd[GICD_ISENABLER0 + (GIC_GPIO_IRQ / 32)] = 1 << (GIC_GPIO_IRQ % 32); + } else { + // Enable interrupts + irpctl[IRPT_ENB_IRQ_2] = (1 << (GPIO_IRQ % 32)); + } +#endif // USE_SEL_EVENT_ENABLE + + // Create work table + + MakeTable(); + + // Finally, enable ENABLE + LOGTRACE("%s Finally, enable ENABLE....", __PRETTY_FUNCTION__); + // Show the user that this app is running + SetControl(PIN_ENB, ENB_ON); + + return true; +#endif // ifdef __x86_64__ || __X86__ +} + +void GPIOBUS_Raspberry::Cleanup() +{ + GPIO_FUNCTION_TRACE +#if defined(__x86_64__) || defined(__X86__) + return; +#else + // Release SEL signal interrupt +#ifdef USE_SEL_EVENT_ENABLE + close(selevreq.fd); +#endif // USE_SEL_EVENT_ENABLE + + // 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); + + // 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); + } + + // Set drive strength back to 8mA + DrvConfig(3); +#endif // ifdef __x86_64__ || __X86__ +} + +void GPIOBUS_Raspberry::Reset() +{ + GPIO_FUNCTION_TRACE +#if defined(__x86_64__) || defined(__X86__) + return; +#else + int i; + int j; + + // Turn off active signal + SetControl(PIN_ACT, ACT_OFF); + + // Set all signals to off + for (i = 0;; i++) { + j = SignalTable[i]; + if (j < 0) { + break; + } + + SetSignal(j, OFF); + } + + if (actmode == mode_e::TARGET) { + // Target mode + + // Set target signal to input + SetControl(PIN_TAD, TAD_IN); + SetMode(PIN_BSY, IN); + SetMode(PIN_MSG, IN); + SetMode(PIN_CD, IN); + SetMode(PIN_REQ, IN); + SetMode(PIN_IO, IN); + + // Set the initiator signal to input + SetControl(PIN_IND, IND_IN); + SetMode(PIN_SEL, IN); + SetMode(PIN_ATN, IN); + SetMode(PIN_ACK, IN); + SetMode(PIN_RST, IN); + + // Set data bus signals to input + SetControl(PIN_DTD, DTD_IN); + SetMode(PIN_DT0, IN); + SetMode(PIN_DT1, IN); + SetMode(PIN_DT2, IN); + SetMode(PIN_DT3, IN); + SetMode(PIN_DT4, IN); + SetMode(PIN_DT5, IN); + SetMode(PIN_DT6, IN); + SetMode(PIN_DT7, IN); + SetMode(PIN_DP, IN); + } else { + // Initiator mode + + // Set target signal to input + SetControl(PIN_TAD, TAD_IN); + SetMode(PIN_BSY, IN); + SetMode(PIN_MSG, IN); + SetMode(PIN_CD, IN); + SetMode(PIN_REQ, IN); + SetMode(PIN_IO, IN); + + // Set the initiator signal to output + SetControl(PIN_IND, IND_OUT); + SetMode(PIN_SEL, OUT); + SetMode(PIN_ATN, OUT); + SetMode(PIN_ACK, OUT); + SetMode(PIN_RST, OUT); + + // Set the data bus signals to output + SetControl(PIN_DTD, DTD_OUT); + SetMode(PIN_DT0, OUT); + SetMode(PIN_DT1, OUT); + SetMode(PIN_DT2, OUT); + SetMode(PIN_DT3, OUT); + SetMode(PIN_DT4, OUT); + SetMode(PIN_DT5, OUT); + SetMode(PIN_DT6, OUT); + SetMode(PIN_DT7, OUT); + SetMode(PIN_DP, OUT); + } + + // Initialize all signals + signals = 0; +#endif // ifdef __x86_64__ || __X86__ +} + +//--------------------------------------------------------------------------- +// +// Get data signals +// +//--------------------------------------------------------------------------- +BYTE GPIOBUS_Raspberry::GetDAT() +{ + GPIO_FUNCTION_TRACE + uint32_t data = Acquire(); + data = ((data >> (PIN_DT0 - 0)) & (1 << 0)) | ((data >> (PIN_DT1 - 1)) & (1 << 1)) | + ((data >> (PIN_DT2 - 2)) & (1 << 2)) | ((data >> (PIN_DT3 - 3)) & (1 << 3)) | + ((data >> (PIN_DT4 - 4)) & (1 << 4)) | ((data >> (PIN_DT5 - 5)) & (1 << 5)) | + ((data >> (PIN_DT6 - 6)) & (1 << 6)) | ((data >> (PIN_DT7 - 7)) & (1 << 7)); + return (BYTE)data; +} + +//--------------------------------------------------------------------------- +// +// Set data signals +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::SetDAT(BYTE dat) +{ + GPIO_FUNCTION_TRACE + // Write to port +#if SIGNAL_CONTROL_MODE == 0 + uint32_t fsel = gpfsel[0]; + fsel &= tblDatMsk[0][dat]; + fsel |= tblDatSet[0][dat]; + if (fsel != gpfsel[0]) { + gpfsel[0] = fsel; + gpio[GPIO_FSEL_0] = fsel; + } + + fsel = gpfsel[1]; + fsel &= tblDatMsk[1][dat]; + fsel |= tblDatSet[1][dat]; + if (fsel != gpfsel[1]) { + gpfsel[1] = fsel; + gpio[GPIO_FSEL_1] = fsel; + } + + fsel = gpfsel[2]; + fsel &= tblDatMsk[2][dat]; + fsel |= tblDatSet[2][dat]; + if (fsel != gpfsel[2]) { + gpfsel[2] = fsel; + gpio[GPIO_FSEL_2] = fsel; + } +#else + gpio[GPIO_CLR_0] = tblDatMsk[dat]; + gpio[GPIO_SET_0] = tblDatSet[dat]; +#endif // SIGNAL_CONTROL_MODE +} + +//--------------------------------------------------------------------------- +// +// Create work table +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::MakeTable(void) +{ + GPIO_FUNCTION_TRACE + + const array pintbl = {PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP}; + + array tblParity; + + // Create parity table + for (uint32_t i = 0; i < 0x100; i++) { + uint32_t bits = i; + uint32_t parity = 0; + for (int j = 0; j < 8; j++) { + parity ^= bits & 1; + bits >>= 1; + } + parity = ~parity; + tblParity[i] = parity & 1; + } + +#if SIGNAL_CONTROL_MODE == 0 + // Mask and setting data generation + for (auto &tbl : tblDatMsk) { + tbl.fill(-1); + } + for (auto &tbl : tblDatSet) { + tbl.fill(0); + } + + for (uint32_t i = 0; i < 0x100; i++) { + // Bit string for inspection + uint32_t bits = i; + + // Get parity + if (tblParity[i]) { + bits |= (1 << 8); + } + + // Bit check + for (int j = 0; j < 9; j++) { + // Index and shift amount calculation + int index = pintbl[j] / 10; + int shift = (pintbl[j] % 10) * 3; + + // Mask data + tblDatMsk[index][i] &= ~(0x7 << shift); + + // Setting data + if (bits & 1) { + tblDatSet[index][i] |= (1 << shift); + } + + bits >>= 1; + } + } +#else + for (uint32_t i = 0; i < 0x100; i++) { + // Bit string for inspection + uint32_t bits = i; + + // Get parity + if (tblParity[i]) { + bits |= (1 << 8); + } + +#if SIGNAL_CONTROL_MODE == 1 + // Negative logic is inverted + bits = ~bits; +#endif + + // Create GPIO register information + uint32_t gpclr = 0; + uint32_t gpset = 0; + for (int j = 0; j < 9; j++) { + if (bits & 1) { + gpset |= (1 << pintbl[j]); + } else { + gpclr |= (1 << pintbl[j]); + } + bits >>= 1; + } + + tblDatMsk[i] = gpclr; + tblDatSet[i] = gpset; + } +#endif +} + +//--------------------------------------------------------------------------- +// +// Control signal setting +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::SetControl(int pin, bool ast) +{ + PinSetSignal(pin, ast); +} + +//--------------------------------------------------------------------------- +// +// Input/output mode setting +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::SetMode(int pin, int mode) +{ +#if SIGNAL_CONTROL_MODE == 0 + if (mode == OUT) { + return; + } +#endif // SIGNAL_CONTROL_MODE + + int index = pin / 10; + int shift = (pin % 10) * 3; + uint32_t data = gpfsel[index]; + data &= ~(0x7 << shift); + if (mode == OUT) { + data |= (1 << shift); + } + gpio[index] = data; + gpfsel[index] = data; +} + +//--------------------------------------------------------------------------- +// +// Get input signal value +// +//--------------------------------------------------------------------------- +bool GPIOBUS_Raspberry::GetSignal(int pin) const +{ + return (signals >> pin) & 1; +} + +//--------------------------------------------------------------------------- +// +// Set output signal value +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::SetSignal(int pin, bool ast) +{ +#if SIGNAL_CONTROL_MODE == 0 + int index = pin / 10; + int shift = (pin % 10) * 3; + uint32_t data = gpfsel[index]; + if (ast) { + data |= (1 << shift); + } else { + data &= ~(0x7 << shift); + } + gpio[index] = data; + gpfsel[index] = data; +#elif SIGNAL_CONTROL_MODE == 1 + if (ast) { + gpio[GPIO_CLR_0] = 0x1 << pin; + } else { + gpio[GPIO_SET_0] = 0x1 << pin; + } +#elif SIGNAL_CONTROL_MODE == 2 + if (ast) { + gpio[GPIO_SET_0] = 0x1 << pin; + } else { + gpio[GPIO_CLR_0] = 0x1 << pin; + } +#endif // SIGNAL_CONTROL_MODE +} + +//--------------------------------------------------------------------------- +// +// Wait for signal change +// +// TODO: maybe this should be moved to SCSI_Bus? +//--------------------------------------------------------------------------- +bool GPIOBUS_Raspberry::WaitSignal(int pin, int ast) +{ + // Get current time + uint32_t now = SysTimer::GetTimerLow(); + + // Calculate timeout (3000ms) + uint32_t timeout = 3000 * 1000; + + // end immediately if the signal has changed + do { + // Immediately upon receiving a reset + Acquire(); + if (GetRST()) { + return false; + } + + // Check for the signal edge + if (((signals >> pin) ^ ~ast) & 1) { + return true; + } + } while ((SysTimer::GetTimerLow() - now) < timeout); + + // We timed out waiting for the signal + return false; +} + +void GPIOBUS_Raspberry::DisableIRQ() +{ + GPIO_FUNCTION_TRACE +#ifdef __linux + if (rpitype == 4) { + // RPI4 is disabled by GICC + giccpmr = gicc[GICC_PMR]; + gicc[GICC_PMR] = 0; + } else if (rpitype == 2) { + // RPI2,3 disable core timer IRQ + tintcore = sched_getcpu() + QA7_CORE0_TINTC; + tintctl = qa7regs[tintcore]; + qa7regs[tintcore] = 0; + } else { + // Stop system timer interrupt with interrupt controller + irptenb = irpctl[IRPT_ENB_IRQ_1]; + irpctl[IRPT_DIS_IRQ_1] = irptenb & 0xf; + } +#else + (void) + 0; +#endif +} + +void GPIOBUS_Raspberry::EnableIRQ() +{ + GPIO_FUNCTION_TRACE + if (rpitype == 4) { + // RPI4 enables interrupts via the GICC + gicc[GICC_PMR] = giccpmr; + } else if (rpitype == 2) { + // RPI2,3 re-enable core timer IRQ + qa7regs[tintcore] = tintctl; + } else { + // Restart the system timer interrupt with the interrupt controller + irpctl[IRPT_ENB_IRQ_1] = irptenb & 0xf; + } +} + +//--------------------------------------------------------------------------- +// +// Pin direction setting (input/output) +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::PinConfig(int pin, int mode) +{ + // Check for invalid pin + if (pin < 0) { + return; + } + + int index = pin / 10; + uint32_t mask = ~(0x7 << ((pin % 10) * 3)); + gpio[index] = (gpio[index] & mask) | ((mode & 0x7) << ((pin % 10) * 3)); +} + +//--------------------------------------------------------------------------- +// +// Pin pull-up/pull-down setting +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::PullConfig(int pin, int mode) +{ + uint32_t pull; + + // Check for invalid pin + if (pin < 0) { + return; + } + + if (rpitype == 4) { + LOGTRACE("%s I'm a Pi 4", __PRETTY_FUNCTION__) + switch (mode) { + case GPIO_PULLNONE: + pull = 0; + break; + case GPIO_PULLUP: + pull = 1; + break; + case GPIO_PULLDOWN: + pull = 2; + break; + default: + return; + } + + pin &= 0x1f; + int shift = (pin & 0xf) << 1; + uint32_t bits = gpio[GPIO_PUPPDN0 + (pin >> 4)]; + bits &= ~(3 << shift); + bits |= (pull << shift); + gpio[GPIO_PUPPDN0 + (pin >> 4)] = bits; + } else { + pin &= 0x1f; + gpio[GPIO_PUD] = mode & 0x3; + SysTimer::SleepUsec(2); + gpio[GPIO_CLK_0] = 0x1 << pin; + SysTimer::SleepUsec(2); + gpio[GPIO_PUD] = 0; + gpio[GPIO_CLK_0] = 0; + } +} + +//--------------------------------------------------------------------------- +// +// Set output pin +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::PinSetSignal(int pin, bool ast) +{ + // Check for invalid pin + if (pin < 0) { + return; + } + + if (ast) { + gpio[GPIO_SET_0] = 0x1 << pin; + } else { + gpio[GPIO_CLR_0] = 0x1 << pin; + } +} + +//--------------------------------------------------------------------------- +// +// Set the signal drive strength +// +//--------------------------------------------------------------------------- +void GPIOBUS_Raspberry::DrvConfig(uint32_t drive) +{ + uint32_t data = pads[PAD_0_27]; + pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000; +} + +uint32_t GPIOBUS_Raspberry::Acquire() +{ + GPIO_FUNCTION_TRACE; +#if defined(__x86_64__) || defined(__X86__) + // Only used for development/debugging purposes. Isn't really applicable + // to any real-world RaSCSI application + return 0; +#else + signals = *level; + +#if SIGNAL_CONTROL_MODE < 2 + // Invert if negative logic (internal processing is unified to positive logic) + signals = ~signals; +#endif // SIGNAL_CONTROL_MODE + return signals; +#endif // ifdef __x86_64__ || __X86__ +} diff --git a/src/raspberrypi/hal/gpiobus_raspberry.h b/src/raspberrypi/hal/gpiobus_raspberry.h new file mode 100644 index 00000000..eb939f35 --- /dev/null +++ b/src/raspberrypi/hal/gpiobus_raspberry.h @@ -0,0 +1,124 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// [ GPIO-SCSI bus ] +// +//--------------------------------------------------------------------------- + +#pragma once + +#include "config.h" +#include "hal/gpiobus.h" +#include "log.h" +#include "scsi.h" + +//--------------------------------------------------------------------------- +// +// Class definition +// +//--------------------------------------------------------------------------- +class GPIOBUS_Raspberry final : public GPIOBUS +{ + public: + // Basic Functions + GPIOBUS_Raspberry() = default; + ~GPIOBUS_Raspberry() override = default; + // Destructor + bool Init(mode_e mode = mode_e::TARGET) override; + // Initialization + void Reset() override; + // Reset + void Cleanup() override; + // Cleanup + + //--------------------------------------------------------------------------- + // + // Bus signal acquisition + // + //--------------------------------------------------------------------------- + uint32_t Acquire() override; + + BYTE GetDAT() override; + // Get DAT signal + void SetDAT(BYTE dat) override; + // Set DAT signal + private: + // SCSI I/O signal control + void MakeTable() override; + // Create work data + void SetControl(int pin, bool ast) override; + // Set Control Signal + void SetMode(int pin, int mode) override; + // Set SCSI I/O mode + bool GetSignal(int pin) const override; + // Get SCSI input signal value + void SetSignal(int pin, bool ast) override; + // Set SCSI output signal value + bool WaitSignal(int pin, int ast) override; + // Wait for a signal to change + // Interrupt control + void DisableIRQ() override; + // IRQ Disabled + void EnableIRQ() override; + // IRQ Enabled + + // GPIO pin functionality settings + void PinConfig(int pin, int mode) override; + // GPIO pin direction setting + void PullConfig(int pin, int mode) override; + // GPIO pin pull up/down resistor setting + void PinSetSignal(int pin, bool ast) override; + // Set GPIO output signal + void DrvConfig(uint32_t drive) override; + // Set GPIO drive strength + +#if !defined(__x86_64__) && !defined(__X86__) + uint32_t baseaddr = 0; // Base address +#endif + + int rpitype = 0; // Type of Raspberry Pi + + volatile uint32_t *gpio = nullptr; // GPIO register + + volatile uint32_t *pads = nullptr; // PADS register + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *level = nullptr; // GPIO input level +#endif + + volatile uint32_t *irpctl = nullptr; // Interrupt control register + + volatile uint32_t irptenb; // Interrupt enabled state + + volatile uint32_t *qa7regs = nullptr; // QA7 register + + volatile int tintcore; // Interupt control target CPU. + + volatile uint32_t tintctl; // Interupt control + + volatile uint32_t giccpmr; // GICC priority setting + +#if !defined(__x86_64__) && !defined(__X86__) + volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register +#endif + + volatile uint32_t *gicc = nullptr; // GIC CPU interface register + + array gpfsel; // GPFSEL0-4 backup values + + uint32_t signals = 0; // All bus signals + +#if SIGNAL_CONTROL_MODE == 0 + array, 3> tblDatMsk; // Data mask table + + array, 3> tblDatSet; // Data setting table +#else + array tblDatMsk = {}; // Data mask table + + array tblDatSet = {}; // Table setting table +#endif +}; diff --git a/src/raspberrypi/hal/gpiobus_standard.h b/src/raspberrypi/hal/gpiobus_standard.h index 502d1e99..f6b3cacd 100644 --- a/src/raspberrypi/hal/gpiobus_standard.h +++ b/src/raspberrypi/hal/gpiobus_standard.h @@ -16,41 +16,41 @@ // RaSCSI standard (SCSI logic, standard pin assignment) // -const std::string CONNECT_DESC = "STANDARD"; // Startup message +const std::string CONNECT_DESC = "STANDARD"; // Startup message // Select signal control mode -const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification +const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification // Control signal pin assignment (-1 means no control) -const static int PIN_ACT = 4; // ACTIVE -const static int PIN_ENB = 5; // ENABLE -const static int PIN_IND = -1; // INITIATOR CTRL DIRECTION -const static int PIN_TAD = -1; // TARGET CTRL DIRECTION -const static int PIN_DTD = -1; // DATA DIRECTION +const static int PIN_ACT = 4; // ACTIVE +const static int PIN_ENB = 5; // ENABLE +const static int PIN_IND = -1; // INITIATOR CTRL DIRECTION +const static int PIN_TAD = -1; // TARGET CTRL DIRECTION +const static int PIN_DTD = -1; // DATA DIRECTION // Control signal output logic -#define ACT_ON ON // ACTIVE SIGNAL ON -#define ENB_ON ON // ENABLE SIGNAL ON -#define IND_IN OFF // INITIATOR SIGNAL INPUT -#define TAD_IN OFF // TARGET SIGNAL INPUT -#define DTD_IN ON // DATA SIGNAL INPUT +#define ACT_ON ON // ACTIVE SIGNAL ON +#define ENB_ON ON // ENABLE SIGNAL ON +#define IND_IN OFF // INITIATOR SIGNAL INPUT +#define TAD_IN OFF // TARGET SIGNAL INPUT +#define DTD_IN ON // DATA SIGNAL INPUT // SCSI signal pin assignment -const static int PIN_DT0 = 10; // Data 0 -const static int PIN_DT1 = 11; // Data 1 -const static int PIN_DT2 = 12; // Data 2 -const static int PIN_DT3 = 13; // Data 3 -const static int PIN_DT4 = 14; // Data 4 -const static int PIN_DT5 = 15; // Data 5 -const static int PIN_DT6 = 16; // Data 6 -const static int PIN_DT7 = 17; // Data 7 -const static int PIN_DP = 18; // Data parity -const static int PIN_ATN = 19; // ATN -const static int PIN_RST = 20; // RST -const static int PIN_ACK = 21; // ACK -const static int PIN_REQ = 22; // REQ -const static int PIN_MSG = 23; // MSG -const static int PIN_CD = 24; // CD -const static int PIN_IO = 25; // IO -const static int PIN_BSY = 26; // BSY -const static int PIN_SEL = 27; // SEL +const static int PIN_DT0 = 10; // Data 0 +const static int PIN_DT1 = 11; // Data 1 +const static int PIN_DT2 = 12; // Data 2 +const static int PIN_DT3 = 13; // Data 3 +const static int PIN_DT4 = 14; // Data 4 +const static int PIN_DT5 = 15; // Data 5 +const static int PIN_DT6 = 16; // Data 6 +const static int PIN_DT7 = 17; // Data 7 +const static int PIN_DP = 18; // Data parity +const static int PIN_ATN = 19; // ATN +const static int PIN_RST = 20; // RST +const static int PIN_ACK = 21; // ACK +const static int PIN_REQ = 22; // REQ +const static int PIN_MSG = 23; // MSG +const static int PIN_CD = 24; // CD +const static int PIN_IO = 25; // IO +const static int PIN_BSY = 26; // BSY +const static int PIN_SEL = 27; // SEL diff --git a/src/raspberrypi/hal/sbc_version.cpp b/src/raspberrypi/hal/sbc_version.cpp new file mode 100644 index 00000000..34a3a3bf --- /dev/null +++ b/src/raspberrypi/hal/sbc_version.cpp @@ -0,0 +1,215 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Copyright (C) 2022 akuker +// +// [ Hardware version detection routines ] +// +//--------------------------------------------------------------------------- + +#include "sbc_version.h" +#include "log.h" +#include +#include +#include + +SBC_Version::sbc_version_type SBC_Version::m_sbc_version = sbc_version_type::sbc_unknown; + +const std::string SBC_Version::m_str_raspberry_pi_1 = "Raspberry Pi 1"; +const std::string SBC_Version::m_str_raspberry_pi_2_3 = "Raspberry Pi 2/3"; +const std::string SBC_Version::m_str_raspberry_pi_4 = "Raspberry Pi 4"; +const std::string SBC_Version::m_str_bananapi_m2_berry = "Banana Pi M2 Berry/Ultra"; +const std::string SBC_Version::m_str_bananapi_m2_zero = "Banana Pi M2 Zero"; +const std::string SBC_Version::m_str_bananapi_m2_plus = "Banana Pi BPI-M2-Plus H3"; +const std::string SBC_Version::m_str_bananapi_m3 = "Banana Pi M3"; +const std::string SBC_Version::m_str_bananapi_m4 = "Banana Pi M4"; +const std::string SBC_Version::m_str_unknown_sbc = "Unknown SBC"; + +// The strings in this table should align with the 'model' embedded +// in the device tree. This can be aquired by running: +// cat /proc/device-tree/model +// Only the first part of the string is checked. Anything following +// will be ignored. For example: +// "Raspberry Pi 4 Model B" will match with both of the following: +// - Raspberry Pi 4 Model B Rev 1.4 +// - Raspberry Pi 4 Model B Rev 1.3 +const std::map SBC_Version::m_proc_device_tree_mapping = { + {"Raspberry Pi 1 Model ", sbc_version_type::sbc_raspberry_pi_1}, + {"Raspberry Pi 2 Model ", sbc_version_type::sbc_raspberry_pi_2_3}, + {"Raspberry Pi 3 Model ", sbc_version_type::sbc_raspberry_pi_2_3}, + {"Raspberry Pi 4 Model ", sbc_version_type::sbc_raspberry_pi_4}, + {"Raspberry Pi 400 ", sbc_version_type::sbc_raspberry_pi_4}, + {"Raspberry Pi Zero W", sbc_version_type::sbc_raspberry_pi_1}, + {"Raspberry Pi Zero", sbc_version_type::sbc_raspberry_pi_1}, + {"Banana Pi BPI-M2-Zero ", sbc_version_type::sbc_bananapi_m2_zero}, + {"Banana Pi BPI-M2-Ultra ", sbc_version_type::sbc_bananapi_m2_berry}, + {"Banana Pi BPI-M2-Plus H3", sbc_version_type::sbc_bananapi_m2_plus}, + {"Banana Pi M2 Berry ", sbc_version_type::sbc_bananapi_m2_berry}, + // sbc_bananapi_m3, TBD.... + // sbc_bananapi_m4, +}; + +const std::string SBC_Version::m_device_tree_model_path = "/proc/device-tree/model"; + +//--------------------------------------------------------------------------- +// +// Convert the SBC Version to a printable string +// +//--------------------------------------------------------------------------- +const std::string *SBC_Version::GetString() +{ + switch (m_sbc_version) { + case sbc_version_type::sbc_raspberry_pi_1: + return &m_str_raspberry_pi_1; + case sbc_version_type::sbc_raspberry_pi_2_3: + return &m_str_raspberry_pi_2_3; + case sbc_version_type::sbc_raspberry_pi_4: + return &m_str_raspberry_pi_4; + case sbc_version_type::sbc_bananapi_m2_berry: + return &m_str_bananapi_m2_berry; + case sbc_version_type::sbc_bananapi_m2_zero: + return &m_str_bananapi_m2_zero; + case sbc_version_type::sbc_bananapi_m2_plus: + return &m_str_bananapi_m2_plus; + case sbc_version_type::sbc_bananapi_m3: + return &m_str_bananapi_m3; + case sbc_version_type::sbc_bananapi_m4: + return &m_str_bananapi_m4; + default: + LOGERROR("Unknown type of sbc detected: %d", static_cast(m_sbc_version)) + return &m_str_unknown_sbc; + } +} + +SBC_Version::sbc_version_type SBC_Version::GetSbcVersion() +{ + return m_sbc_version; +} + +//--------------------------------------------------------------------------- +// +// Determine which version of single board computer (Pi) is being used +// based upon the device tree model string. +// +//--------------------------------------------------------------------------- +void SBC_Version::Init() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + std::string device_tree_model; + + const std::ifstream input_stream(SBC_Version::m_device_tree_model_path); + + if (input_stream.fail()) { + LOGERROR("Failed to open %s. Are you running as root?", SBC_Version::m_device_tree_model_path.c_str()) + throw std::invalid_argument("Failed to open /proc/device-tree/model"); + } + + std::stringstream str_buffer; + str_buffer << input_stream.rdbuf(); + device_tree_model = str_buffer.str(); + + for (const auto &[key, value] : m_proc_device_tree_mapping) { + if (device_tree_model.rfind(key, 0) == 0) { + m_sbc_version = value; + LOGINFO("Detected device %s", GetString()->c_str()) + return; + } + } + LOGERROR("%s Unable to determine single board computer type. Defaulting to Raspberry Pi 4", __PRETTY_FUNCTION__) + m_sbc_version = sbc_version_type::sbc_raspberry_pi_4; +} + +bool SBC_Version::IsRaspberryPi() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + switch (m_sbc_version) { + case sbc_version_type::sbc_raspberry_pi_1: + case sbc_version_type::sbc_raspberry_pi_2_3: + case sbc_version_type::sbc_raspberry_pi_4: + return true; + case sbc_version_type::sbc_bananapi_m2_berry: + case sbc_version_type::sbc_bananapi_m2_zero: + case sbc_version_type::sbc_bananapi_m2_plus: + case sbc_version_type::sbc_bananapi_m3: + case sbc_version_type::sbc_bananapi_m4: + return false; + default: + return false; + } +} + +bool SBC_Version::IsBananaPi() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + switch (m_sbc_version) { + case sbc_version_type::sbc_raspberry_pi_1: + case sbc_version_type::sbc_raspberry_pi_2_3: + case sbc_version_type::sbc_raspberry_pi_4: + return false; + case sbc_version_type::sbc_bananapi_m2_berry: + case sbc_version_type::sbc_bananapi_m2_zero: + case sbc_version_type::sbc_bananapi_m2_plus: + case sbc_version_type::sbc_bananapi_m3: + case sbc_version_type::sbc_bananapi_m4: + return true; + default: + return false; + } +} + +// The following functions are only used on the Raspberry Pi +// (imported from bcm_host.c) +DWORD SBC_Version::GetDeviceTreeRanges(const char *filename, DWORD offset) +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + DWORD address = ~0; + if (FILE *fp = fopen(filename, "rb"); fp) { + fseek(fp, offset, SEEK_SET); + if (std::array buf; fread(buf.data(), 1, buf.size(), fp) == buf.size()) { + address = (int)buf[0] << 24 | (int)buf[1] << 16 | (int)buf[2] << 8 | (int)buf[3] << 0; + } + fclose(fp); + } + return address; +} + +#if defined __linux__ +DWORD SBC_Version::GetPeripheralAddress(void) +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + DWORD address = GetDeviceTreeRanges("/proc/device-tree/soc/ranges", 4); + if (address == 0) { + address = GetDeviceTreeRanges("/proc/device-tree/soc/ranges", 8); + } + address = (address == (DWORD)~0) ? 0x20000000 : address; + + LOGDEBUG("Peripheral address : 0x%8x\n", address) + + return address; +} +#elif defined __NetBSD__ +DWORD SBC_Version::GetPeripheralAddress(void) +{ + char buf[1024]; + size_t len = sizeof(buf); + DWORD address; + + if (sysctlbyname("hw.model", buf, &len, NULL, 0) || strstr(buf, "ARM1176JZ-S") != buf) { + // Failed to get CPU model || Not BCM2835 + // use the address of BCM283[67] + address = 0x3f000000; + } else { + // Use BCM2835 address + address = 0x20000000; + } + LOGDEBUG("Peripheral address : 0x%lx\n", address); + return address; +} +#else +DWORD SBC_Version::GetPeripheralAddress(void) +{ + return 0; +} +#endif \ No newline at end of file diff --git a/src/raspberrypi/hal/sbc_version.h b/src/raspberrypi/hal/sbc_version.h new file mode 100644 index 00000000..6d788423 --- /dev/null +++ b/src/raspberrypi/hal/sbc_version.h @@ -0,0 +1,70 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Copyright (C) 2022 akuker +// +// [ Hardware version detection routines ] +// +//--------------------------------------------------------------------------- + +#pragma once +#include "os.h" +#include +#include + +//=========================================================================== +// +// Single Board Computer Versions +// +//=========================================================================== +class SBC_Version +{ + public: + // Type of Single Board Computer + enum class sbc_version_type : uint8_t { + sbc_unknown = 0, + sbc_raspberry_pi_1, + sbc_raspberry_pi_2_3, + sbc_raspberry_pi_4, + sbc_bananapi_m2_berry, + sbc_bananapi_m2_zero, + sbc_bananapi_m2_plus, + sbc_bananapi_m3, + sbc_bananapi_m4, + }; + + SBC_Version() = delete; + ~SBC_Version() = delete; + + static void Init(); + + static sbc_version_type GetSbcVersion(); + + static bool IsRaspberryPi(); + static bool IsBananaPi(); + + static const std::string *GetString(); + + static DWORD GetPeripheralAddress(); + + private: + static sbc_version_type m_sbc_version; + + static const std::string m_str_raspberry_pi_1; + static const std::string m_str_raspberry_pi_2_3; + static const std::string m_str_raspberry_pi_4; + static const std::string m_str_bananapi_m2_berry; + static const std::string m_str_bananapi_m2_zero; + static const std::string m_str_bananapi_m2_plus; + static const std::string m_str_bananapi_m3; + static const std::string m_str_bananapi_m4; + static const std::string m_str_unknown_sbc; + + static const std::map m_proc_device_tree_mapping; + + static const std::string m_device_tree_model_path; + + static DWORD GetDeviceTreeRanges(const char *filename, DWORD offset); +}; \ No newline at end of file diff --git a/src/raspberrypi/hal/systimer.cpp b/src/raspberrypi/hal/systimer.cpp index 6677cc9c..628994fe 100644 --- a/src/raspberrypi/hal/systimer.cpp +++ b/src/raspberrypi/hal/systimer.cpp @@ -12,129 +12,57 @@ //--------------------------------------------------------------------------- #include "hal/systimer.h" -#include "hal/gpiobus.h" -#include "config.h" +#include "hal/systimer_allwinner.h" +#include "hal/systimer_raspberry.h" #include -#include -#include -#include -#include -//--------------------------------------------------------------------------- -// -// System timer address -// -//--------------------------------------------------------------------------- -volatile uint32_t* SysTimer::systaddr; +#include "hal/gpiobus.h" +#include "hal/sbc_version.h" +#include "os.h" -//--------------------------------------------------------------------------- -// -// ARM timer address -// -//--------------------------------------------------------------------------- -volatile uint32_t* SysTimer::armtaddr; +#include "config.h" +#include "log.h" -//--------------------------------------------------------------------------- -// -// Core frequency -// -//--------------------------------------------------------------------------- -volatile DWORD SysTimer::corefreq; +bool SysTimer::initialized = false; +bool SysTimer::is_allwinnner = false; +bool SysTimer::is_raspberry = false; -//--------------------------------------------------------------------------- -// -// Initialize the system timer -// -//--------------------------------------------------------------------------- -void SysTimer::Init(uint32_t *syst, uint32_t *armt) +std::unique_ptr SysTimer::systimer_ptr; + +void SysTimer::Init() { - // RPI Mailbox property interface - // Get max clock rate - // Tag: 0x00030004 - // - // Request: Length: 4 - // Value: u32: clock id - // Response: Length: 8 - // Value: u32: clock id, u32: rate (in Hz) - // - // Clock id - // 0x000000004: CORE - array maxclock = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 }; + LOGTRACE("%s", __PRETTY_FUNCTION__) - // Save the base address - systaddr = syst; - armtaddr = armt; - - // Change the ARM timer to free run mode - armtaddr[ARMT_CTRL] = 0x00000282; - - // Get the core frequency - corefreq = 0; - int fd = open("/dev/vcio", O_RDONLY); - if (fd >= 0) { - ioctl(fd, _IOWR(100, 0, char *), maxclock); - corefreq = maxclock[6] / 1000000; - } - close(fd); + if (!initialized) { + if (SBC_Version::IsRaspberryPi()) { + systimer_ptr = make_unique(); + is_raspberry = true; + } else if (SBC_Version::IsBananaPi()) { + systimer_ptr = make_unique(); + is_allwinnner = true; + } + systimer_ptr->Init(); + initialized = true; + } } -//--------------------------------------------------------------------------- -// -// Get system timer low byte -// -//--------------------------------------------------------------------------- -uint32_t SysTimer::GetTimerLow() { - return systaddr[SYST_CLO]; -} - -//--------------------------------------------------------------------------- -// -// Get system timer high byte -// -//--------------------------------------------------------------------------- -uint32_t SysTimer::GetTimerHigh() { - return systaddr[SYST_CHI]; -} - -//--------------------------------------------------------------------------- -// -// Sleep in nanoseconds -// -//--------------------------------------------------------------------------- -void SysTimer::SleepNsec(DWORD nsec) +// Get system timer low byte +uint32_t SysTimer::GetTimerLow() { - // If time is 0, don't do anything - if (nsec == 0) { - return; - } - - // Calculate the timer difference - uint32_t diff = corefreq * nsec / 1000; - - // Return if the difference in time is too small - if (diff == 0) { - return; - } - - // Start - uint32_t start = armtaddr[ARMT_FREERUN]; - - // Loop until timer has elapsed - while ((armtaddr[ARMT_FREERUN] - start) < diff); + return systimer_ptr->GetTimerLow(); } - -//--------------------------------------------------------------------------- -// -// Sleep in microseconds -// -//--------------------------------------------------------------------------- -void SysTimer::SleepUsec(DWORD usec) +// Get system timer high byte +uint32_t SysTimer::GetTimerHigh() { - // If time is 0, don't do anything - if (usec == 0) { - return; - } - - uint32_t now = GetTimerLow(); - while ((GetTimerLow() - now) < usec); + return systimer_ptr->GetTimerHigh(); +} +// Sleep for N nanoseconds +void SysTimer::SleepNsec(uint32_t nsec) +{ + systimer_ptr->SleepNsec(nsec); +} +// Sleep for N microseconds +void SysTimer::SleepUsec(uint32_t usec) +{ + systimer_ptr->SleepUsec(usec); } diff --git a/src/raspberrypi/hal/systimer.h b/src/raspberrypi/hal/systimer.h index 8f4b31d9..746afa62 100644 --- a/src/raspberrypi/hal/systimer.h +++ b/src/raspberrypi/hal/systimer.h @@ -13,11 +13,31 @@ #pragma once +#include #include #include "config.h" #include "scsi.h" +class PlatformSpecificTimer +{ + public: + // Default constructor + PlatformSpecificTimer() = default; + // Default destructor + virtual ~PlatformSpecificTimer() = default; + // Initialization + virtual void Init() = 0; + // Get system timer low byte + virtual uint32_t GetTimerLow() = 0; + // Get system timer high byte + virtual uint32_t GetTimerHigh() = 0; + // Sleep for N nanoseconds + virtual void SleepNsec(uint32_t nsec) = 0; + // Sleep for N microseconds + virtual void SleepUsec(uint32_t usec) = 0; +}; + //=========================================================================== // // System timer @@ -25,23 +45,21 @@ //=========================================================================== class SysTimer { -public: - static void Init(uint32_t *syst, uint32_t *armt); - // Initialization - static uint32_t GetTimerLow(); - // Get system timer low byte - static uint32_t GetTimerHigh(); - // Get system timer high byte - static void SleepNsec(uint32_t nsec); - // Sleep for N nanoseconds - static void SleepUsec(uint32_t usec); - // Sleep for N microseconds + public: + static void Init(); + // Get system timer low byte + static uint32_t GetTimerLow(); + // Get system timer high byte + static uint32_t GetTimerHigh(); + // Sleep for N nanoseconds + static void SleepNsec(uint32_t nsec); + // Sleep for N microseconds + static void SleepUsec(uint32_t usec); -private: - static volatile uint32_t *systaddr; - // System timer address - static volatile uint32_t *armtaddr; - // ARM timer address - static volatile uint32_t corefreq; - // Core frequency + private: + static bool initialized; + static bool is_allwinnner; + static bool is_raspberry; + + static std::unique_ptr systimer_ptr; }; diff --git a/src/raspberrypi/hal/systimer_allwinner.cpp b/src/raspberrypi/hal/systimer_allwinner.cpp new file mode 100644 index 00000000..08cde859 --- /dev/null +++ b/src/raspberrypi/hal/systimer_allwinner.cpp @@ -0,0 +1,156 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Copyright (C) 2022 akuker +// +// [ High resolution timer for the Allwinner series of SoC's] +// +//--------------------------------------------------------------------------- + +#include "hal/systimer_allwinner.h" +#include + +#include "hal/gpiobus.h" +#include "os.h" + +#include "config.h" +#include "log.h" + +const std::string SysTimer_AllWinner::dev_mem_filename = "/dev/mem"; + +//--------------------------------------------------------------------------- +// +// Initialize the system timer +// +//--------------------------------------------------------------------------- +void SysTimer_AllWinner::Init() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + + int fd; + + if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) { + LOGERROR("I can't open /dev/mem. Are you running as root?") + exit(-1); + } + + hsitimer_regs = (struct sun8i_hsitimer_registers *)mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + hs_timer_base_address); + + if (hsitimer_regs == MAP_FAILED) { + LOGERROR("Unable to map high speed timer registers. Are you running as root?") + } + + sysbus_regs = (struct sun8i_sysbus_registers *)mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + system_bus_base_address); + + if (sysbus_regs == MAP_FAILED) { + LOGERROR("Unable to map system bus registers. Are you running as root?") + } + + enable_hs_timer(); +} + +void SysTimer_AllWinner::enable_hs_timer() +{ + // By default, the HSTimer clock gating is masked. When it is necessary to use + // the HSTimer, its clock gating should be opened in BUS Clock Gating Register 0 + // and then de-assert the software reset in BUS Software Reset Register 0 on the + // CCU module. If it is not needed to use the HSTimer, both the gating bit and + // the software reset bit should be set 0. + + LOGTRACE("%s [Before Enable] CLK GATE: %08X SOFT RST: %08X", __PRETTY_FUNCTION__, sysbus_regs->bus_clk_gating_reg0, + sysbus_regs->bus_soft_rst_reg0) + + sysbus_regs->bus_clk_gating_reg0 = sysbus_regs->bus_clk_gating_reg0 | (1 << BUS_CLK_GATING_REG0_HSTMR); + sysbus_regs->bus_soft_rst_reg0 = sysbus_regs->bus_soft_rst_reg0 | (1 << BUS_SOFT_RST_REG0_HSTMR); + LOGTRACE("%s [After Enable] CLK GATE: %08X SOFT RST: %08X", __PRETTY_FUNCTION__, sysbus_regs->bus_clk_gating_reg0, + sysbus_regs->bus_soft_rst_reg0) + + // Set interval value to the maximum value. (its a 52 bit register) + hsitimer_regs->hs_tmr_intv_hi_reg = (1 << 20) - 1; //(0xFFFFF) + hsitimer_regs->hs_tmr_intv_lo_reg = UINT32_MAX; + + // Select prescale value of 1, continuouse mode + hsitimer_regs->hs_tmr_ctrl_reg = HS_TMR_CLK_PRE_SCALE_1; + + // Set reload bit + hsitimer_regs->hs_tmr_ctrl_reg |= HS_TMR_RELOAD; + + // Enable HSTimer + hsitimer_regs->hs_tmr_ctrl_reg |= HS_TMR_EN; +} + +// TODO: According to the data sheet, we should turn off the HS timer when we're done with it. But, its just going to +// eat up a little extra power if we leave it running. +void SysTimer_AllWinner::disable_hs_timer() +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + + LOGINFO("[Before Disable] CLK GATE: %08X SOFT RST: %08X", sysbus_regs->bus_clk_gating_reg0, + sysbus_regs->bus_soft_rst_reg0) + + sysbus_regs->bus_clk_gating_reg0 = sysbus_regs->bus_clk_gating_reg0 & ~(1 << BUS_CLK_GATING_REG0_HSTMR); + sysbus_regs->bus_soft_rst_reg0 = sysbus_regs->bus_soft_rst_reg0 & ~(1 << BUS_SOFT_RST_REG0_HSTMR); + + LOGINFO("[After Disable] CLK GATE: %08X SOFT RST: %08X", sysbus_regs->bus_clk_gating_reg0, + sysbus_regs->bus_soft_rst_reg0) +} + +DWORD SysTimer_AllWinner::GetTimerLow() +{ + // RaSCSI expects the timer to count UP, but the Allwinner HS timer counts + // down. So, we subtract the current timer value from UINT32_MAX + return UINT32_MAX - (hsitimer_regs->hs_tmr_curnt_lo_reg / 200); +} + +DWORD SysTimer_AllWinner::GetTimerHigh() +{ + return (uint32_t)0; +} + +//--------------------------------------------------------------------------- +// +// Sleep in nanoseconds +// +//--------------------------------------------------------------------------- +void SysTimer_AllWinner::SleepNsec(DWORD nsec) +{ + // If time is less than one HS timer clock tick, don't do anything + if (nsec < 20) { + return; + } + + // The HS timer receives a 200MHz clock input, which equates to + // one clock tick every 5 ns. + auto clockticks = (uint32_t)std::ceil(nsec / 5); + + DWORD enter_time = hsitimer_regs->hs_tmr_curnt_lo_reg; + + LOGTRACE("%s entertime: %08X ns: %d clockticks: %d", __PRETTY_FUNCTION__, enter_time, nsec, clockticks) + while ((enter_time - hsitimer_regs->hs_tmr_curnt_lo_reg) < clockticks) + ; + + return; +} + +//--------------------------------------------------------------------------- +// +// Sleep in microseconds +// +//--------------------------------------------------------------------------- +void SysTimer_AllWinner::SleepUsec(DWORD usec) +{ + LOGTRACE("%s", __PRETTY_FUNCTION__) + + // If time is 0, don't do anything + if (usec == 0) { + return; + } + + DWORD enter_time = GetTimerLow(); + while ((GetTimerLow() - enter_time) < usec) + ; +} diff --git a/src/raspberrypi/hal/systimer_allwinner.h b/src/raspberrypi/hal/systimer_allwinner.h new file mode 100644 index 00000000..72036e47 --- /dev/null +++ b/src/raspberrypi/hal/systimer_allwinner.h @@ -0,0 +1,106 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Copyright (C) 2022 akuker +// +// [ High resolution timer ] +// +//--------------------------------------------------------------------------- +#pragma once + +#include "systimer.h" +#include +#include + +//=========================================================================== +// +// System timer +// +//=========================================================================== +class SysTimer_AllWinner : public PlatformSpecificTimer +{ + public: + // Default constructor + SysTimer_AllWinner() = default; + // Default destructor + ~SysTimer_AllWinner() override = default; + // Initialization + void Init() override; + // Get system timer low byte + uint32_t GetTimerLow() override; + // Get system timer high byte + uint32_t GetTimerHigh() override; + // Sleep for N nanoseconds + void SleepNsec(uint32_t nsec) override; + // Sleep for N microseconds + void SleepUsec(uint32_t usec) override; + + private: + void enable_hs_timer(); + void disable_hs_timer(); + + static const std::string dev_mem_filename; + + /* Reference: Allwinner H3 Datasheet, section 4.9.3 */ + static const uint32_t hs_timer_base_address = 0x01C60000; + /* Note: Currently the high speed timer is NOT in the armbian + * device tree. If it is ever added, this should be pulled + * from there */ + + struct sun8i_hsitimer_registers { + /* 0x00 HS Timer IRQ Enabled Register */ + uint32_t hs_tmr_irq_en_reg; + /* 0x04 HS Timer Status Register */ + uint32_t hs_tmr_irq_stat_reg; + /* 0x08 Unused */ + uint32_t unused_08; + /* 0x0C Unused */ + uint32_t unused_0C; + /* 0x10 HS Timer Control Register */ + uint32_t hs_tmr_ctrl_reg; + /* 0x14 HS Timer Interval Value Low Reg */ + uint32_t hs_tmr_intv_lo_reg; + /* 0x18 HS Timer Interval Value High Register */ + uint32_t hs_tmr_intv_hi_reg; + /* 0x1C HS Timer Current Value Low Register */ + uint32_t hs_tmr_curnt_lo_reg; + /* 0x20 HS Timer Current Value High Register */ + uint32_t hs_tmr_curnt_hi_reg; + }; + + /* Constants for the HS Timer IRQ enable Register (section 4.9.4.1) */ + static const uint32_t HS_TMR_INTERUPT_ENB = (1 << 0); + + /* Constants for the HS Timer Control Register (section 4.9.4.3) */ + static const uint32_t HS_TMR_EN = (1 << 0); + static const uint32_t HS_TMR_RELOAD = (1 << 1); + static const uint32_t HS_TMR_CLK_PRE_SCALE_1 = (0 << 4); + static const uint32_t HS_TMR_CLK_PRE_SCALE_2 = (1 << 4); + static const uint32_t HS_TMR_CLK_PRE_SCALE_4 = (2 << 4); + static const uint32_t HS_TMR_CLK_PRE_SCALE_8 = (3 << 4); + static const uint32_t HS_TMR_CLK_PRE_SCALE_16 = (4 << 4); // NOSONAR This matches the datasheet + static const uint32_t HS_TMR_MODE_SINGLE = (1 << 7); + static const uint32_t HS_TMR_TEST_MODE = (1 << 31); + + struct sun8i_hsitimer_registers *hsitimer_regs; + + /* Reference: Allwinner H3 Datasheet, section 4.3.4 */ + static const uint32_t system_bus_base_address = 0x01C20000; + + struct sun8i_sysbus_registers { + uint32_t pad_00_5C[(0x60 / sizeof(uint32_t))]; //NOSONAR c-style array used for padding + /* 0x0060 Bus Clock Gating Register 0 */ + uint32_t bus_clk_gating_reg0; + uint32_t pad_64_2C0[((0x2C0 - 0x64) / sizeof(uint32_t))]; //NOSONAR c-style array used for padding + /* 0x2C0 Bus Software Reset Register 0 */ + uint32_t bus_soft_rst_reg0; + }; + + /* Bit associated with the HS Timer */ + static const uint32_t BUS_CLK_GATING_REG0_HSTMR = 19; + static const uint32_t BUS_SOFT_RST_REG0_HSTMR = 19; + + struct sun8i_sysbus_registers *sysbus_regs; +}; diff --git a/src/raspberrypi/hal/systimer_raspberry.cpp b/src/raspberrypi/hal/systimer_raspberry.cpp new file mode 100644 index 00000000..5ecc8ca6 --- /dev/null +++ b/src/raspberrypi/hal/systimer_raspberry.cpp @@ -0,0 +1,149 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// Copyright (C) 2022 akuker +// +// [ High resolution timer ] +// +//--------------------------------------------------------------------------- + +#include "hal/systimer_raspberry.h" +#include +#include +#include + +#include "hal/gpiobus.h" +#include "hal/sbc_version.h" +#include "os.h" + +#include "config.h" +#include "log.h" + +// System timer address +volatile uint32_t *SysTimer_Raspberry::systaddr = nullptr; +// ARM timer address +volatile uint32_t *SysTimer_Raspberry::armtaddr = nullptr; +volatile uint32_t SysTimer_Raspberry::corefreq = 0; + +//--------------------------------------------------------------------------- +// +// Initialize the system timer +// +//--------------------------------------------------------------------------- +void SysTimer_Raspberry::Init() +{ + // Get the base address + auto baseaddr = SBC_Version::GetPeripheralAddress(); + + // Open /dev/mem + int mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + if (mem_fd == -1) { + LOGERROR("Error: Unable to open /dev/mem. Are you running as root?") + return; + } + + // Map peripheral region memory + void *map = mmap(nullptr, 0x1000100, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, baseaddr); + if (map == MAP_FAILED) { + LOGERROR("Error: Unable to map memory") + close(mem_fd); + return; + } + close(mem_fd); + + // RPI Mailbox property interface + // Get max clock rate + // Tag: 0x00030004 + // + // Request: Length: 4 + // Value: u32: clock id + // Response: Length: 8 + // Value: u32: clock id, u32: rate (in Hz) + // + // Clock id + // 0x000000004: CORE + std::array maxclock = {32, 0, 0x00030004, 8, 0, 4, 0, 0}; + + // Save the base address + systaddr = (DWORD *)map + SYST_OFFSET / sizeof(DWORD); + armtaddr = (DWORD *)map + ARMT_OFFSET / sizeof(DWORD); + + // Change the ARM timer to free run mode + armtaddr[ARMT_CTRL] = 0x00000282; + + // Get the core frequency + if (int vcio_fd = open("/dev/vcio", O_RDONLY); vcio_fd >= 0) { + ioctl(vcio_fd, _IOWR(100, 0, char *), maxclock.data()); + corefreq = maxclock[6] / 1000000; + close(vcio_fd); + } +} + +//--------------------------------------------------------------------------- +// +// Get system timer low byte +// +//--------------------------------------------------------------------------- +DWORD SysTimer_Raspberry::GetTimerLow() +{ + return systaddr[SYST_CLO]; +} + +//--------------------------------------------------------------------------- +// +// Get system timer high byte +// +//--------------------------------------------------------------------------- +DWORD SysTimer_Raspberry::GetTimerHigh() +{ + return systaddr[SYST_CHI]; +} + +//--------------------------------------------------------------------------- +// +// Sleep in nanoseconds +// +//--------------------------------------------------------------------------- +void SysTimer_Raspberry::SleepNsec(DWORD nsec) +{ + // If time is 0, don't do anything + if (nsec == 0) { + return; + } + + // Calculate the timer difference + DWORD diff = corefreq * nsec / 1000; + + // Return if the difference in time is too small + if (diff == 0) { + return; + } + + // Start + DWORD start = armtaddr[ARMT_FREERUN]; + + // Loop until timer has elapsed + while ((armtaddr[ARMT_FREERUN] - start) < diff) + ; +} + +//--------------------------------------------------------------------------- +// +// Sleep in microseconds +// +//--------------------------------------------------------------------------- +void SysTimer_Raspberry::SleepUsec(DWORD usec) +{ + // If time is 0, don't do anything + if (usec == 0) { + return; + } + + DWORD now = GetTimerLow(); + while ((GetTimerLow() - now) < usec) + ; +} diff --git a/src/raspberrypi/hal/systimer_raspberry.h b/src/raspberrypi/hal/systimer_raspberry.h new file mode 100644 index 00000000..f126bd11 --- /dev/null +++ b/src/raspberrypi/hal/systimer_raspberry.h @@ -0,0 +1,49 @@ +//--------------------------------------------------------------------------- +// +// SCSI Target Emulator RaSCSI Reloaded +// for Raspberry Pi +// +// Powered by XM6 TypeG Technology. +// Copyright (C) 2016-2020 GIMONS +// Copyright (C) 2022 akuker +// +// [ High resolution timer ] +// +//--------------------------------------------------------------------------- + +#pragma once + +#include "systimer.h" +#include + +//=========================================================================== +// +// System timer +// +//=========================================================================== +class SysTimer_Raspberry : public PlatformSpecificTimer +{ + public: + // Default constructor + SysTimer_Raspberry() = default; + // Default destructor + ~SysTimer_Raspberry() override = default; + // Initialization + void Init() override; + // Get system timer low byte + uint32_t GetTimerLow() override; + // Get system timer high byte + uint32_t GetTimerHigh() override; + // Sleep for N nanoseconds + void SleepNsec(uint32_t nsec) override; + // Sleep for N microseconds + void SleepUsec(uint32_t usec) override; + + private: + // System timer address + static volatile uint32_t *systaddr; + // ARM timer address + static volatile uint32_t *armtaddr; + // Core frequency + static volatile uint32_t corefreq; +}; diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index f0c267c3..312a58af 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -17,6 +17,8 @@ #include "devices/device_factory.h" #include "devices/disk.h" #include "hal/gpiobus.h" +#include "hal/gpiobus_factory.h" +#include "hal/sbc_version.h" #include "hal/systimer.h" #include "rascsi_version.h" #include "rascsi_exceptions.h" @@ -59,14 +61,14 @@ static const char COMPONENT_SEPARATOR = ':'; //--------------------------------------------------------------------------- static volatile bool active; // Processing flag RascsiService service; -GPIOBUS bus; +shared_ptr bus; string current_log_level = "info"; // Some versions of spdlog do not support get_log_level() string access_token; DeviceFactory device_factory; -ControllerManager controller_manager(bus); +shared_ptr controller_manager; RascsiImage rascsi_image; -RascsiResponse rascsi_response(device_factory, controller_manager, ScsiController::LUN_MAX); -RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); +shared_ptr rascsi_response; +shared_ptr executor; const ProtobufSerializer serializer; void Banner(int argc, char* argv[]) @@ -96,32 +98,42 @@ void Banner(int argc, char* argv[]) bool InitBus() { + SBC_Version::Init(); + // GPIOBUS creation + bus = GPIOBUS_Factory::Create(); + + + controller_manager = make_shared(bus); + rascsi_response = make_shared(device_factory, *controller_manager, ScsiController::LUN_MAX); + executor = make_shared(*rascsi_response, rascsi_image, device_factory, *controller_manager); + + // GPIO Initialization - if (!bus.Init()) { + if (!bus->Init()) { return false; } // Bus Reset - bus.Reset(); + bus->Reset(); return true; } void Cleanup() { - executor.DetachAll(); + executor->DetachAll(); service.Cleanup(); // Clean up and discard the bus - bus.Cleanup(); + bus->Cleanup(); } void Reset() { - controller_manager.ResetAllControllers(); + controller_manager->ResetAllControllers(); - bus.Reset(); + bus->Reset(); } bool ReadAccessToken(const char *filename) @@ -282,7 +294,7 @@ bool ParseArgument(int argc, char* argv[], int& port) continue; case 'r': { - string error = executor.SetReservedIds(optarg); + string error = executor->SetReservedIds(optarg); if (!error.empty()) { cerr << error << endl; return false; @@ -343,20 +355,20 @@ bool ParseArgument(int argc, char* argv[], int& port) name = ""; } - if (!log_level.empty() && executor.SetLogLevel(log_level)) { + if (!log_level.empty() && executor->SetLogLevel(log_level)) { current_log_level = log_level; } // Attach all specified devices command.set_operation(ATTACH); - if (CommandContext context(locale); !executor.ProcessCmd(context, command)) { + if (CommandContext context(locale); !executor->ProcessCmd(context, command)) { return false; } // Display and log the device list PbServerInfo server_info; - rascsi_response.GetDevices(server_info, rascsi_image.GetDefaultFolder()); + rascsi_response->GetDevices(server_info, rascsi_image.GetDefaultFolder()); const list& devices = { server_info.devices_info().devices().begin(), server_info.devices_info().devices().end() }; const string device_list = ListDevices(devices); LogDevices(device_list); @@ -384,7 +396,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) switch(command.operation()) { case LOG_LEVEL: { const string log_level = GetParam(command, "level"); - if (const bool status = executor.SetLogLevel(log_level); !status) { + if (const bool status = executor->SetLogLevel(log_level); !status) { context.ReturnLocalizedError(LocalizationKey::ERROR_LOG_LEVEL, log_level); } else { @@ -406,20 +418,20 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) } case DEVICES_INFO: { - rascsi_response.GetDevicesInfo(result, command, rascsi_image.GetDefaultFolder()); + rascsi_response->GetDevicesInfo(result, command, rascsi_image.GetDefaultFolder()); serializer.SerializeMessage(context.GetFd(), result); break; } case DEVICE_TYPES_INFO: { - result.set_allocated_device_types_info(rascsi_response.GetDeviceTypesInfo(result).release()); + result.set_allocated_device_types_info(rascsi_response->GetDeviceTypesInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case SERVER_INFO: { - result.set_allocated_server_info(rascsi_response.GetServerInfo( - result, executor.GetReservedIds(), current_log_level, rascsi_image.GetDefaultFolder(), + result.set_allocated_server_info(rascsi_response->GetServerInfo( + result, executor->GetReservedIds(), current_log_level, rascsi_image.GetDefaultFolder(), GetParam(command, "folder_pattern"), GetParam(command, "file_pattern"), rascsi_image.GetDepth()).release()); serializer.SerializeMessage(context.GetFd(), result); @@ -427,19 +439,19 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) } case VERSION_INFO: { - result.set_allocated_version_info(rascsi_response.GetVersionInfo(result).release()); + result.set_allocated_version_info(rascsi_response->GetVersionInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case LOG_LEVEL_INFO: { - result.set_allocated_log_level_info(rascsi_response.GetLogLevelInfo(result, current_log_level).release()); + result.set_allocated_log_level_info(rascsi_response->GetLogLevelInfo(result, current_log_level).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case DEFAULT_IMAGE_FILES_INFO: { - result.set_allocated_image_files_info(rascsi_response.GetAvailableImages(result, + result.set_allocated_image_files_info(rascsi_response->GetAvailableImages(result, rascsi_image.GetDefaultFolder(), GetParam(command, "folder_pattern"), GetParam(command, "file_pattern"), rascsi_image.GetDepth()).release()); serializer.SerializeMessage(context.GetFd(), result); @@ -452,7 +464,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) } else { auto image_file = make_unique(); - const bool status = rascsi_response.GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename); + const bool status = rascsi_response->GetImageFile(*image_file.get(), rascsi_image.GetDefaultFolder(), filename); if (status) { result.set_status(true); result.set_allocated_image_file_info(image_file.get()); @@ -466,33 +478,33 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) } case NETWORK_INTERFACES_INFO: { - result.set_allocated_network_interfaces_info(rascsi_response.GetNetworkInterfacesInfo(result).release()); + result.set_allocated_network_interfaces_info(rascsi_response->GetNetworkInterfacesInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case MAPPING_INFO: { - result.set_allocated_mapping_info(rascsi_response.GetMappingInfo(result).release()); + result.set_allocated_mapping_info(rascsi_response->GetMappingInfo(result).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case OPERATION_INFO: { - result.set_allocated_operation_info(rascsi_response.GetOperationInfo(result, + result.set_allocated_operation_info(rascsi_response->GetOperationInfo(result, rascsi_image.GetDepth()).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case RESERVED_IDS_INFO: { - result.set_allocated_reserved_ids_info(rascsi_response.GetReservedIds(result, - executor.GetReservedIds()).release()); + result.set_allocated_reserved_ids_info(rascsi_response->GetReservedIds(result, + executor->GetReservedIds()).release()); serializer.SerializeMessage(context.GetFd(), result); break; } case SHUT_DOWN: { - if (executor.ShutDown(context, GetParam(command, "mode"))) { + if (executor->ShutDown(context, GetParam(command, "mode"))) { TerminationHandler(0); } break; @@ -505,7 +517,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command) nanosleep(&ts, nullptr); } - executor.ProcessCmd(context, command); + executor->ProcessCmd(context, command); break; } } @@ -532,7 +544,7 @@ int main(int argc, char* argv[]) } } - executor.SetLogLevel(current_log_level); + executor->SetLogLevel(current_log_level); // Create a thread-safe stdout logger to process the log messages const auto logger = stdout_color_mt("rascsi stdout logger"); @@ -581,7 +593,7 @@ int main(int argc, char* argv[]) while (service.IsRunning()) { #ifdef USE_SEL_EVENT_ENABLE // SEL signal polling - if (!bus.PollSelectEvent()) { + if (!bus->PollSelectEvent()) { // Stop on interrupt if (errno == EINTR) { break; @@ -590,10 +602,10 @@ int main(int argc, char* argv[]) } // Get the bus - bus.Acquire(); + bus->Acquire(); #else - bus.Acquire(); - if (!bus.GetSEL()) { + bus->Acquire(); + if (!bus->GetSEL()) { const timespec ts = { .tv_sec = 0, .tv_nsec = 0}; nanosleep(&ts, nullptr); continue; @@ -602,30 +614,30 @@ int main(int argc, char* argv[]) // Wait until BSY is released as there is a possibility for the // initiator to assert it while setting the ID (for up to 3 seconds) - if (bus.GetBSY()) { + if (bus->GetBSY()) { const uint32_t now = SysTimer::GetTimerLow(); while ((SysTimer::GetTimerLow() - now) < 3'000'000) { - bus.Acquire(); - if (!bus.GetBSY()) { + bus->Acquire(); + if (!bus->GetBSY()) { break; } } } // Stop because the bus is busy or another device responded - if (bus.GetBSY() || !bus.GetSEL()) { + if (bus->GetBSY() || !bus->GetSEL()) { continue; } int initiator_id = -1; // The initiator and target ID - const BYTE id_data = bus.GetDAT(); + const BYTE id_data = bus->GetDAT(); BUS::phase_t phase = BUS::phase_t::busfree; // Identify the responsible controller - shared_ptr controller = controller_manager.IdentifyController(id_data); + shared_ptr controller = controller_manager->IdentifyController(id_data); if (controller != nullptr) { initiator_id = controller->ExtractInitiatorId(id_data); diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index 348decd4..afffff46 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -16,6 +16,7 @@ #include "fileio.h" #include "filepath.h" #include "hal/gpiobus.h" +#include "hal/gpiobus_factory.h" #include "hal/systimer.h" #include "rascsi_version.h" #include @@ -36,7 +37,7 @@ static const int BUFSIZE = 1024 * 64; // Buffer size of about 64KB // Variable Declaration // //--------------------------------------------------------------------------- -GPIOBUS bus; // Bus +unique_ptr bus; // GPIO Bus // Bus int targetid; // Target ID int boardid; // Board ID (own ID) Filepath hdsfile; // HDS file @@ -106,8 +107,10 @@ bool Init() return false; } + bus = GPIOBUS_Factory::Create(); + // GPIO Initialization - if (!bus.Init(BUS::mode_e::INITIATOR)) { + if (!bus->Init(BUS::mode_e::INITIATOR)) { return false; } @@ -127,7 +130,7 @@ bool Init() void Cleanup() { // Cleanup the bus - bus.Cleanup(); + bus->Cleanup(); } //--------------------------------------------------------------------------- @@ -138,7 +141,7 @@ void Cleanup() void Reset() { // Reset the bus signal line - bus.Reset(); + bus->Reset(); } //--------------------------------------------------------------------------- @@ -219,8 +222,8 @@ bool WaitPhase(BUS::phase_t phase) // Timeout (3000ms) const uint32_t now = SysTimer::GetTimerLow(); while ((SysTimer::GetTimerLow() - now) < 3 * 1000 * 1000) { - bus.Acquire(); - if (bus.GetREQ() && bus.GetPhase() == phase) { + bus->Acquire(); + if (bus->GetREQ() && bus->GetPhase() == phase) { return true; } } @@ -236,7 +239,7 @@ bool WaitPhase(BUS::phase_t phase) void BusFree() { // Bus Reset - bus.Reset(); + bus->Reset(); } //--------------------------------------------------------------------------- @@ -249,8 +252,8 @@ bool Selection(int id) // ID setting and SEL assert BYTE data = 1 << boardid; data |= (1 << id); - bus.SetDAT(data); - bus.SetSEL(true); + bus->SetDAT(data); + bus->SetSEL(true); // wait for busy int count = 10000; @@ -258,17 +261,17 @@ bool Selection(int id) // Wait 20 microseconds const timespec ts = { .tv_sec = 0, .tv_nsec = 20 * 1000}; nanosleep(&ts, nullptr); - bus.Acquire(); - if (bus.GetBSY()) { + bus->Acquire(); + if (bus->GetBSY()) { break; } } while (count--); // SEL negate - bus.SetSEL(false); + bus->SetSEL(false); // Success if the target is busy - return bus.GetBSY(); + return bus->GetBSY(); } //--------------------------------------------------------------------------- @@ -284,7 +287,7 @@ bool Command(BYTE *buf, int length) } // Send Command - const int count = bus.SendHandShake(buf, length, BUS::SEND_NO_DELAY); + const int count = bus->SendHandShake(buf, length, BUS::SEND_NO_DELAY); // Success if the transmission result is the same as the number // of requests @@ -309,7 +312,7 @@ int DataIn(BYTE *buf, int length) } // Data reception - return bus.ReceiveHandShake(buf, length); + return bus->ReceiveHandShake(buf, length); } //--------------------------------------------------------------------------- @@ -325,7 +328,7 @@ int DataOut(BYTE *buf, int length) } // Data transmission - return bus.SendHandShake(buf, length, BUS::SEND_NO_DELAY); + return bus->SendHandShake(buf, length, BUS::SEND_NO_DELAY); } //--------------------------------------------------------------------------- @@ -343,7 +346,7 @@ int Status() } // Data reception - if (bus.ReceiveHandShake(buf, 1) == 1) { + if (bus->ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } @@ -366,7 +369,7 @@ int MessageIn() } // Data reception - if (bus.ReceiveHandShake(buf, 1) == 1) { + if (bus->ReceiveHandShake(buf, 1) == 1) { return (int)buf[0]; } @@ -846,11 +849,11 @@ int main(int argc, char* argv[]) BusFree(); // Assert reset signal - bus.SetRST(true); + bus->SetRST(true); // Wait 1 ms const timespec ts = { .tv_sec = 0, .tv_nsec = 1000 * 1000}; nanosleep(&ts, nullptr); - bus.SetRST(false); + bus->SetRST(false); // Start dump printf("TARGET ID : %d\n", targetid); diff --git a/src/raspberrypi/scsimon.cpp b/src/raspberrypi/scsimon.cpp index d24f1436..45798ac2 100644 --- a/src/raspberrypi/scsimon.cpp +++ b/src/raspberrypi/scsimon.cpp @@ -11,6 +11,7 @@ #include "os.h" #include "log.h" #include "hal/gpiobus.h" +#include "hal/gpiobus_factory.h" #include "rascsi_version.h" #include #include @@ -32,7 +33,7 @@ static const int _MAX_FNAME = 256; // //--------------------------------------------------------------------------- static volatile bool running; // Running flag -GPIOBUS bus; // GPIO Bus +unique_ptr bus; // GPIO Bus uint32_t buff_size = 1000000; data_capture *data_buffer; @@ -179,14 +180,15 @@ bool Init() } // GPIO Initialization - if (!bus.Init()) + bus = GPIOBUS_Factory::Create(); + if (!bus->Init()) { LOGERROR("Unable to intiailize the GPIO bus. Exiting....") return false; } // Bus Reset - bus.Reset(); + bus->Reset(); // Other running = false; @@ -208,13 +210,13 @@ void Cleanup() scsimon_generate_html(html_file_name, data_buffer, data_idx); // Cleanup the Bus - bus.Cleanup(); + bus->Cleanup(); } void Reset() { // Reset the bus - bus.Reset(); + bus->Reset(); } //--------------------------------------------------------------------------- @@ -325,7 +327,7 @@ int main(int argc, char *argv[]) // Start execution running = true; - bus.SetACT(false); + bus->SetACT(false); (void)gettimeofday(&start_time, nullptr); @@ -335,7 +337,7 @@ int main(int argc, char *argv[]) while (running) { // Work initialization - this_sample = (bus.Acquire() & ALL_SCSI_PINS); + this_sample = (bus->Acquire() & ALL_SCSI_PINS); loop_count++; if (loop_count > LLONG_MAX - 1) { diff --git a/src/raspberrypi/test/abstract_controller_test.cpp b/src/raspberrypi/test/abstract_controller_test.cpp index 8218c30f..cbe20115 100644 --- a/src/raspberrypi/test/abstract_controller_test.cpp +++ b/src/raspberrypi/test/abstract_controller_test.cpp @@ -16,7 +16,7 @@ using namespace scsi_defs; TEST(AbstractControllerTest, AllocateCmd) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); EXPECT_EQ(16, controller.GetCmd().size()); controller.AllocateCmd(1234); @@ -25,7 +25,7 @@ TEST(AbstractControllerTest, AllocateCmd) TEST(AbstractControllerTest, AllocateBuffer) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); controller.AllocateBuffer(1); EXPECT_LE(1, controller.GetBuffer().size()); @@ -35,7 +35,7 @@ TEST(AbstractControllerTest, AllocateBuffer) TEST(AbstractControllerTest, Reset) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -50,7 +50,7 @@ TEST(AbstractControllerTest, Reset) TEST(AbstractControllerTest, ByteTransfer) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); controller.SetByteTransfer(false); EXPECT_FALSE(controller.IsByteTransfer()); @@ -60,14 +60,14 @@ TEST(AbstractControllerTest, ByteTransfer) TEST(AbstractControllerTest, GetMaxLuns) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); EXPECT_EQ(32, controller.GetMaxLuns()); } TEST(AbstractControllerTest, Status) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); controller.SetStatus(status::RESERVATION_CONFLICT); EXPECT_EQ(status::RESERVATION_CONFLICT, controller.GetStatus()); @@ -75,7 +75,7 @@ TEST(AbstractControllerTest, Status) TEST(AbstractControllerTest, ProcessPhase) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); controller.SetPhase(BUS::phase_t::selection); EXPECT_CALL(controller, Selection()); @@ -121,7 +121,8 @@ TEST(AbstractControllerTest, DeviceLunLifeCycle) const int ID = 1; const int LUN = 4; - MockAbstractController controller(ID); + MockAbstractController controller(make_shared(), ID); + auto device1 = make_shared(LUN); auto device2 = make_shared(32); auto device3 = make_shared(-1); @@ -146,7 +147,7 @@ TEST(AbstractControllerTest, ExtractInitiatorId) const int INITIATOR_ID = 7; const int UNKNOWN_INITIATOR_ID = -1; - MockAbstractController controller(ID); + MockAbstractController controller(make_shared(), ID); EXPECT_EQ(INITIATOR_ID, controller.ExtractInitiatorId((1 << INITIATOR_ID) | ( 1 << ID))); EXPECT_EQ(UNKNOWN_INITIATOR_ID, controller.ExtractInitiatorId(1 << ID)); @@ -154,7 +155,7 @@ TEST(AbstractControllerTest, ExtractInitiatorId) TEST(AbstractControllerTest, GetOpcode) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); vector& cmd = controller.GetCmd(); @@ -166,7 +167,7 @@ TEST(AbstractControllerTest, GetLun) { const int LUN = 3; - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); vector& cmd = controller.GetCmd(); @@ -176,7 +177,7 @@ TEST(AbstractControllerTest, GetLun) TEST(AbstractControllerTest, SetLength) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); EXPECT_FALSE(controller.HasValidLength()); @@ -187,7 +188,7 @@ TEST(AbstractControllerTest, SetLength) TEST(AbstractControllerTest, UpdateOffsetAndLength) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); EXPECT_FALSE(controller.HasValidLength()); @@ -197,7 +198,7 @@ TEST(AbstractControllerTest, UpdateOffsetAndLength) TEST(AbstractControllerTest, Offset) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); controller.ResetOffset(); EXPECT_EQ(0, controller.GetOffset()); diff --git a/src/raspberrypi/test/controller_manager_test.cpp b/src/raspberrypi/test/controller_manager_test.cpp index e64b31a5..fd0fa564 100644 --- a/src/raspberrypi/test/controller_manager_test.cpp +++ b/src/raspberrypi/test/controller_manager_test.cpp @@ -17,8 +17,8 @@ TEST(ControllerManagerTest, LifeCycle) const int LUN1 = 0; const int LUN2 = 3; - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; auto device = device_factory.CreateDevice(controller_manager, SCHS, -1, ""); @@ -52,8 +52,8 @@ TEST(ControllerManagerTest, AttachToScsiController) const int LUN1 = 3; const int LUN2 = 0; - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; auto device1 = device_factory.CreateDevice(controller_manager, SCHS, LUN1, ""); @@ -69,8 +69,8 @@ TEST(ControllerManagerTest, ResetAllControllers) { const int ID = 2; - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, ""); diff --git a/src/raspberrypi/test/device_factory_test.cpp b/src/raspberrypi/test/device_factory_test.cpp index 877b64c1..c976d2fc 100644 --- a/src/raspberrypi/test/device_factory_test.cpp +++ b/src/raspberrypi/test/device_factory_test.cpp @@ -122,9 +122,9 @@ TEST(DeviceFactoryTest, GetDefaultParams) TEST(DeviceFactoryTest, UnknownDeviceType) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device1 = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test"); EXPECT_EQ(nullptr, device1); @@ -138,9 +138,9 @@ TEST(DeviceFactoryTest, UnknownDeviceType) TEST(DeviceFactoryTest, SCHD_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.hda"); EXPECT_NE(nullptr, device); @@ -177,9 +177,9 @@ TEST(DeviceFactoryTest, SCHD_Device_Defaults) void TestRemovableDrive(PbDeviceType type, const string& filename, const string& product) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, filename); EXPECT_NE(nullptr, device); @@ -215,9 +215,9 @@ TEST(DeviceFactoryTest, SCMO_Device_Defaults) TEST(DeviceFactoryTest, SCCD_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "test.iso"); EXPECT_NE(nullptr, device); @@ -242,9 +242,9 @@ TEST(DeviceFactoryTest, SCCD_Device_Defaults) TEST(DeviceFactoryTest, SCBR_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "bridge"); EXPECT_NE(nullptr, device); @@ -269,9 +269,9 @@ TEST(DeviceFactoryTest, SCBR_Device_Defaults) TEST(DeviceFactoryTest, SCDP_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "daynaport"); EXPECT_NE(nullptr, device); @@ -295,9 +295,9 @@ TEST(DeviceFactoryTest, SCDP_Device_Defaults) TEST(DeviceFactoryTest, SCHS_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "services"); EXPECT_NE(nullptr, device); @@ -322,9 +322,9 @@ TEST(DeviceFactoryTest, SCHS_Device_Defaults) TEST(DeviceFactoryTest, SCLP_Device_Defaults) { - MockBus bus; + auto bus_ptr = make_shared(); DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(bus_ptr); auto device = device_factory.CreateDevice(controller_manager, UNDEFINED, 0, "printer"); EXPECT_NE(nullptr, device); diff --git a/src/raspberrypi/test/disk_test.cpp b/src/raspberrypi/test/disk_test.cpp index c22ec752..afb4845c 100644 --- a/src/raspberrypi/test/disk_test.cpp +++ b/src/raspberrypi/test/disk_test.cpp @@ -18,7 +18,7 @@ using namespace scsi_command_util; TEST(DiskTest, Dispatch) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); const unordered_set sector_sizes; auto disk = make_shared(); @@ -33,7 +33,7 @@ TEST(DiskTest, Dispatch) TEST(DiskTest, Rezero) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -50,7 +50,7 @@ TEST(DiskTest, Rezero) TEST(DiskTest, FormatUnit) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -72,7 +72,7 @@ TEST(DiskTest, FormatUnit) TEST(DiskTest, ReassignBlocks) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -89,7 +89,7 @@ TEST(DiskTest, ReassignBlocks) TEST(DiskTest, Seek6) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -114,7 +114,7 @@ TEST(DiskTest, Seek6) TEST(DiskTest, Seek10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -139,7 +139,7 @@ TEST(DiskTest, Seek10) TEST(DiskTest, ReadCapacity) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -203,7 +203,7 @@ TEST(DiskTest, ReadCapacity) TEST(DiskTest, Read6) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -216,7 +216,7 @@ TEST(DiskTest, Read6) TEST(DiskTest, Read10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -234,7 +234,7 @@ TEST(DiskTest, Read10) TEST(DiskTest, Read16) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -252,7 +252,7 @@ TEST(DiskTest, Read16) TEST(DiskTest, Write6) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -265,7 +265,7 @@ TEST(DiskTest, Write6) TEST(DiskTest, Write10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -283,7 +283,7 @@ TEST(DiskTest, Write10) TEST(DiskTest, Write16) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -301,7 +301,7 @@ TEST(DiskTest, Write16) TEST(DiskTest, Verify10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -319,7 +319,7 @@ TEST(DiskTest, Verify10) TEST(DiskTest, Verify16) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -337,7 +337,7 @@ TEST(DiskTest, Verify16) TEST(DiskTest, ReadLong10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -360,7 +360,7 @@ TEST(DiskTest, ReadLong10) TEST(DiskTest, ReadLong16) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -385,7 +385,7 @@ TEST(DiskTest, ReadLong16) TEST(DiskTest, WriteLong10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -408,7 +408,7 @@ TEST(DiskTest, WriteLong10) TEST(DiskTest, WriteLong16) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -431,7 +431,7 @@ TEST(DiskTest, WriteLong16) TEST(DiskTest, StartStopUnit) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); disk->SetRemovable(true); @@ -481,7 +481,7 @@ TEST(DiskTest, StartStopUnit) TEST(DiskTest, PreventAllowMediumRemoval) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -566,7 +566,7 @@ void DiskTest_ValidateCachePage(AbstractController& controller, int offset) TEST(DiskTest, ModeSense6) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -617,7 +617,7 @@ TEST(DiskTest, ModeSense6) TEST(DiskTest, ModeSense10) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -694,7 +694,7 @@ TEST(DiskTest, ModeSense10) TEST(DiskTest, SynchronizeCache) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); @@ -712,7 +712,7 @@ TEST(DiskTest, SynchronizeCache) TEST(DiskTest, ReadDefectData) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto disk = make_shared(); controller.AddDevice(disk); diff --git a/src/raspberrypi/test/host_services_test.cpp b/src/raspberrypi/test/host_services_test.cpp index f7cd802f..c887a82f 100644 --- a/src/raspberrypi/test/host_services_test.cpp +++ b/src/raspberrypi/test/host_services_test.cpp @@ -21,7 +21,7 @@ TEST(HostServicesTest, Dispatch) TEST(HostServicesTest, TestUnitReady) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto services = CreateDevice(SCHS, controller); EXPECT_CALL(controller, Status()); @@ -36,7 +36,7 @@ TEST(HostServicesTest, Inquiry) TEST(HostServicesTest, StartStopUnit) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto services = CreateDevice(SCHS, controller); vector& cmd = controller.GetCmd(); @@ -68,7 +68,7 @@ TEST(HostServicesTest, StartStopUnit) TEST(HostServicesTest, ModeSense6) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto services = CreateDevice(SCHS, controller); vector& cmd = controller.GetCmd(); @@ -105,7 +105,7 @@ TEST(HostServicesTest, ModeSense6) TEST(HostServicesTest, ModeSense10) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto services = CreateDevice(SCHS, controller); vector& cmd = controller.GetCmd(); @@ -142,8 +142,7 @@ TEST(HostServicesTest, ModeSense10) TEST(HostServicesTest, SetUpModePages) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); MockHostServices services(0, controller_manager); map> pages; diff --git a/src/raspberrypi/test/mocks.h b/src/raspberrypi/test/mocks.h index fa6198ac..6253466a 100644 --- a/src/raspberrypi/test/mocks.h +++ b/src/raspberrypi/test/mocks.h @@ -150,15 +150,13 @@ public: MOCK_METHOD(void, MsgOut, (), ()); MOCK_METHOD(void, ScheduleShutdown, (rascsi_shutdown_mode), (override)); - explicit MockAbstractController(int target_id) : AbstractController(bus, target_id, 32) { + explicit MockAbstractController(shared_ptr bus, int target_id) : AbstractController(bus, target_id, 32) { AllocateBuffer(512); } ~MockAbstractController() override = default; // Permit access to all tests without the need for numerous FRIEND_TEST vector& GetCmd() { return AbstractController::GetCmd(); } //NOSONAR Hides function on purpose - - MockBus bus; }; class MockScsiController : public ScsiController @@ -182,11 +180,10 @@ public: MOCK_METHOD(void, Execute, (), ()); using ScsiController::ScsiController; - explicit MockScsiController(int target_id) : ScsiController(bus, target_id) {} - MockScsiController() : ScsiController(bus, 0) {} + explicit MockScsiController(shared_ptr bus, int target_id) : ScsiController(bus, target_id) {} + MockScsiController(shared_ptr bus) : ScsiController(bus, 0) {} ~MockScsiController() override = default; - NiceMock bus; }; class MockDevice : public Device diff --git a/src/raspberrypi/test/mode_page_device_test.cpp b/src/raspberrypi/test/mode_page_device_test.cpp index 1e7e5810..a7c178af 100644 --- a/src/raspberrypi/test/mode_page_device_test.cpp +++ b/src/raspberrypi/test/mode_page_device_test.cpp @@ -72,7 +72,7 @@ TEST(ModePageDeviceTest, AddVendorPage) TEST(ModePageDeviceTest, Dispatch) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared>(); controller.AddDevice(device); @@ -82,7 +82,7 @@ TEST(ModePageDeviceTest, Dispatch) TEST(ModePageDeviceTest, ModeSense6) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared>(); controller.AddDevice(device); @@ -93,7 +93,7 @@ TEST(ModePageDeviceTest, ModeSense6) TEST(ModePageDeviceTest, ModeSense10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared>(); controller.AddDevice(device); @@ -116,7 +116,7 @@ TEST(ModePageDeviceTest, ModeSelect) TEST(ModePageDeviceTest, ModeSelect6) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(); controller.AddDevice(device); @@ -133,7 +133,7 @@ TEST(ModePageDeviceTest, ModeSelect6) TEST(ModePageDeviceTest, ModeSelect10) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(); controller.AddDevice(device); diff --git a/src/raspberrypi/test/primary_device_test.cpp b/src/raspberrypi/test/primary_device_test.cpp index ff7bf73f..b9b9c45d 100644 --- a/src/raspberrypi/test/primary_device_test.cpp +++ b/src/raspberrypi/test/primary_device_test.cpp @@ -19,7 +19,7 @@ TEST(PrimaryDeviceTest, GetId) { const int ID = 5; - MockAbstractController controller(ID); + MockAbstractController controller(make_shared(), ID); auto device = make_shared(0); EXPECT_EQ(-1, device->GetId()) << "Device ID cannot be known without assignment to a controller"; @@ -30,7 +30,7 @@ TEST(PrimaryDeviceTest, GetId) TEST(PrimaryDeviceTest, PhaseChange) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -47,7 +47,7 @@ TEST(PrimaryDeviceTest, PhaseChange) TEST(PrimaryDeviceTest, Reset) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -62,7 +62,7 @@ TEST(PrimaryDeviceTest, Reset) TEST(PrimaryDeviceTest, CheckReservation) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -92,7 +92,7 @@ TEST(PrimaryDeviceTest, CheckReservation) TEST(PrimaryDeviceTest, ReserveReleaseUnit) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -117,7 +117,7 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit) TEST(PrimaryDeviceTest, DiscardReservation) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -132,7 +132,7 @@ TEST(PrimaryDeviceTest, DiscardReservation) TEST(PrimaryDeviceTest, TestUnitReady) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -169,7 +169,7 @@ TEST(PrimaryDeviceTest, TestUnitReady) TEST(PrimaryDeviceTest, Inquiry) { - auto controller = make_shared>(0); + auto controller = make_shared>(make_shared(), 0); auto device = make_shared(0); controller->AddDevice(device); @@ -231,7 +231,7 @@ TEST(PrimaryDeviceTest, Inquiry) TEST(PrimaryDeviceTest, RequestSense) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -251,7 +251,7 @@ TEST(PrimaryDeviceTest, RequestSense) TEST(PrimaryDeviceTest, SendDiagnostic) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -281,7 +281,7 @@ TEST(PrimaryDeviceTest, ReportLuns) const int LUN1 = 1; const int LUN2 = 4; - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device1 = make_shared(LUN1); auto device2 = make_shared(LUN2); @@ -324,7 +324,7 @@ TEST(PrimaryDeviceTest, ReportLuns) TEST(PrimaryDeviceTest, UnknownCommand) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared(0); controller.AddDevice(device); @@ -334,7 +334,7 @@ TEST(PrimaryDeviceTest, UnknownCommand) TEST(PrimaryDeviceTest, Dispatch) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared>(0); controller.AddDevice(device); diff --git a/src/raspberrypi/test/rascsi_executor_test.cpp b/src/raspberrypi/test/rascsi_executor_test.cpp index 810bd1e2..c691d7cd 100644 --- a/src/raspberrypi/test/rascsi_executor_test.cpp +++ b/src/raspberrypi/test/rascsi_executor_test.cpp @@ -38,10 +38,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) const int ID = 3; const int LUN = 0; - MockBus bus; + shared_ptr bus_ptr = make_shared(); DeviceFactory device_factory; - MockAbstractController controller(ID); - ControllerManager controller_manager(bus); + MockAbstractController controller(bus_ptr, ID); + ControllerManager controller_manager(bus_ptr); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); auto executor = make_shared(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -151,10 +151,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd) TEST_F(RascsiExecutorTest, ProcessCmd) { - MockBus bus; + shared_ptr bus_ptr; DeviceFactory device_factory; - MockAbstractController controller(0); - ControllerManager controller_manager(bus); + MockAbstractController controller(bus_ptr, 0); + ControllerManager controller_manager(bus_ptr); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); auto executor = make_shared(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -218,9 +218,8 @@ TEST_F(RascsiExecutorTest, ProcessCmd) TEST_F(RascsiExecutorTest, SetLogLevel) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -239,9 +238,8 @@ TEST_F(RascsiExecutorTest, Attach) const int ID = 3; const int LUN = 0; - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -321,9 +319,8 @@ TEST_F(RascsiExecutorTest, Attach) TEST_F(RascsiExecutorTest, Insert) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -382,9 +379,8 @@ TEST_F(RascsiExecutorTest, Detach) const int LUN1 = 0; const int LUN2 = 1; - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -409,9 +405,8 @@ TEST_F(RascsiExecutorTest, DetachAll) { const int ID = 4; - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -428,9 +423,8 @@ TEST_F(RascsiExecutorTest, DetachAll) TEST_F(RascsiExecutorTest, ShutDown) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -445,9 +439,8 @@ TEST_F(RascsiExecutorTest, ShutDown) TEST_F(RascsiExecutorTest, SetReservedIds) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -486,9 +479,8 @@ TEST_F(RascsiExecutorTest, SetReservedIds) TEST_F(RascsiExecutorTest, ValidateImageFile) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -505,9 +497,8 @@ TEST_F(RascsiExecutorTest, ValidateImageFile) TEST_F(RascsiExecutorTest, ValidateLunSetup) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -534,9 +525,8 @@ TEST_F(RascsiExecutorTest, VerifyExistingIdAndLun) const int LUN1 = 0; const int LUN2 = 3; - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -551,9 +541,8 @@ TEST_F(RascsiExecutorTest, VerifyExistingIdAndLun) TEST_F(RascsiExecutorTest, CreateDevice) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -570,9 +559,8 @@ TEST_F(RascsiExecutorTest, CreateDevice) TEST_F(RascsiExecutorTest, SetSectorSize) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -591,9 +579,8 @@ TEST_F(RascsiExecutorTest, SetSectorSize) TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -646,9 +633,8 @@ TEST_F(RascsiExecutorTest, ValidateOperationAgainstDevice) TEST_F(RascsiExecutorTest, ValidateIdAndLun) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); @@ -664,9 +650,8 @@ TEST_F(RascsiExecutorTest, ValidateIdAndLun) TEST_F(RascsiExecutorTest, SetProductData) { - MockBus bus; DeviceFactory device_factory; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); RascsiImage rascsi_image; RascsiResponse rascsi_response(device_factory, controller_manager, 32); RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager); diff --git a/src/raspberrypi/test/rascsi_response_test.cpp b/src/raspberrypi/test/rascsi_response_test.cpp index 130aff53..263bbee8 100644 --- a/src/raspberrypi/test/rascsi_response_test.cpp +++ b/src/raspberrypi/test/rascsi_response_test.cpp @@ -18,8 +18,8 @@ using namespace rascsi_interface; TEST(RascsiResponseTest, Operation_Count) { - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; @@ -30,8 +30,8 @@ TEST(RascsiResponseTest, Operation_Count) void TestNonDiskDevice(PbDeviceType type, int default_param_count) { - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); @@ -70,8 +70,7 @@ TEST(RascsiResponseTest, GetDevices) TEST(RascsiResponseTest, GetImageFile) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbImageFile image_file; @@ -86,8 +85,8 @@ TEST(RascsiResponseTest, GetImageFile) TEST(RascsiResponseTest, GetReservedIds) { - MockBus bus; - ControllerManager controller_manager(bus); + auto bus_ptr = make_shared(); + ControllerManager controller_manager(bus_ptr); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); unordered_set ids; @@ -111,8 +110,7 @@ TEST(RascsiResponseTest, GetDevicesInfo) const int LUN2 = 5; const int LUN3 = 6; - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbCommand command; @@ -160,8 +158,7 @@ TEST(RascsiResponseTest, GetDevicesInfo) TEST(RascsiResponseTest, GetDeviceTypesInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; @@ -173,8 +170,7 @@ TEST(RascsiResponseTest, GetDeviceTypesInfo) TEST(RascsiResponseTest, GetServerInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); const unordered_set ids = { 1, 3 }; @@ -193,8 +189,7 @@ TEST(RascsiResponseTest, GetServerInfo) TEST(RascsiResponseTest, GetVersionInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; @@ -208,8 +203,7 @@ TEST(RascsiResponseTest, GetVersionInfo) TEST(RascsiResponseTest, GetLogLevelInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; @@ -222,8 +216,7 @@ TEST(RascsiResponseTest, GetLogLevelInfo) TEST(RascsiResponseTest, GetNetworkInterfacesInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; @@ -235,8 +228,7 @@ TEST(RascsiResponseTest, GetNetworkInterfacesInfo) TEST(RascsiResponseTest, GetMappingInfo) { - MockBus bus; - ControllerManager controller_manager(bus); + ControllerManager controller_manager(make_shared()); DeviceFactory device_factory; RascsiResponse response(device_factory, controller_manager, 32); PbResult result; diff --git a/src/raspberrypi/test/scsi_controller_test.cpp b/src/raspberrypi/test/scsi_controller_test.cpp index e797d182..f4573a3d 100644 --- a/src/raspberrypi/test/scsi_controller_test.cpp +++ b/src/raspberrypi/test/scsi_controller_test.cpp @@ -18,7 +18,7 @@ TEST(ScsiControllerTest, GetInitiatorId) { const int ID = 2; - MockScsiController controller; + MockScsiController controller(make_shared()); controller.Process(ID); EXPECT_EQ(ID, controller.GetInitiatorId()); @@ -28,34 +28,34 @@ TEST(ScsiControllerTest, GetInitiatorId) TEST(ScsiControllerTest, Process) { - NiceMock bus; - MockScsiController controller(bus, 0); + auto bus = make_shared>(); + MockScsiController controller(bus); controller.SetPhase(BUS::phase_t::reserved); - ON_CALL(bus, GetRST).WillByDefault(Return(true)); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST); - EXPECT_CALL(bus, Reset); + ON_CALL(*bus, GetRST).WillByDefault(Return(true)); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST); + EXPECT_CALL(*bus, Reset); EXPECT_CALL(controller, Reset); EXPECT_EQ(BUS::phase_t::reserved, controller.Process(0)); controller.SetPhase(BUS::phase_t::busfree); - ON_CALL(bus, GetRST).WillByDefault(Return(false)); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST); + ON_CALL(*bus, GetRST).WillByDefault(Return(false)); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST); EXPECT_EQ(BUS::phase_t::busfree, controller.Process(0)); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST); - EXPECT_CALL(bus, Reset); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST); + EXPECT_CALL(*bus, Reset); EXPECT_CALL(controller, Reset); EXPECT_EQ(BUS::phase_t::busfree, controller.Process(0)); } TEST(ScsiControllerTest, BusFree) { - MockScsiController controller; + MockScsiController controller(make_shared()); controller.SetPhase(BUS::phase_t::busfree); controller.BusFree(); @@ -86,80 +86,80 @@ TEST(ScsiControllerTest, BusFree) TEST(ScsiControllerTest, Selection) { - NiceMock bus; - NiceMock controller(bus, 0); + auto bus = make_shared(); + MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::selection); - ON_CALL(bus, GetSEL).WillByDefault(Return(true)); - ON_CALL(bus, GetBSY).WillByDefault(Return(true)); - EXPECT_CALL(bus, GetATN).Times(0); + ON_CALL(*bus, GetSEL).WillByDefault(Return(true)); + ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); + EXPECT_CALL(*bus, GetATN).Times(0); controller.Selection(); EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); - ON_CALL(bus, GetSEL).WillByDefault(Return(true)); - ON_CALL(bus, GetBSY).WillByDefault(Return(false)); - EXPECT_CALL(bus, GetATN).Times(0); + ON_CALL(*bus, GetSEL).WillByDefault(Return(true)); + ON_CALL(*bus, GetBSY).WillByDefault(Return(false)); + EXPECT_CALL(*bus, GetATN).Times(0); controller.Selection(); EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); - ON_CALL(bus, GetSEL).WillByDefault(Return(false)); - ON_CALL(bus, GetBSY).WillByDefault(Return(false)); - EXPECT_CALL(bus, GetATN).Times(0); + ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); + ON_CALL(*bus, GetBSY).WillByDefault(Return(false)); + EXPECT_CALL(*bus, GetATN).Times(0); controller.Selection(); EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); - ON_CALL(bus, GetSEL).WillByDefault(Return(false)); - ON_CALL(bus, GetBSY).WillByDefault(Return(true)); - ON_CALL(bus, GetATN).WillByDefault(Return(false)); - EXPECT_CALL(bus, GetATN); + ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); + ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); + ON_CALL(*bus, GetATN).WillByDefault(Return(false)); + EXPECT_CALL(*bus, GetATN); controller.Selection(); EXPECT_EQ(BUS::phase_t::command, controller.GetPhase()); controller.SetPhase(BUS::phase_t::selection); - ON_CALL(bus, GetSEL).WillByDefault(Return(false)); - ON_CALL(bus, GetBSY).WillByDefault(Return(true)); - ON_CALL(bus, GetATN).WillByDefault(Return(true)); - EXPECT_CALL(bus, GetATN); + ON_CALL(*bus, GetSEL).WillByDefault(Return(false)); + ON_CALL(*bus, GetBSY).WillByDefault(Return(true)); + ON_CALL(*bus, GetATN).WillByDefault(Return(true)); + EXPECT_CALL(*bus, GetATN); controller.Selection(); EXPECT_EQ(BUS::phase_t::msgout, controller.GetPhase()); controller.SetPhase(BUS::phase_t::reserved); - ON_CALL(bus, GetDAT).WillByDefault(Return(0)); + ON_CALL(*bus, GetDAT).WillByDefault(Return(0)); controller.Selection(); EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()); - ON_CALL(bus, GetDAT).WillByDefault(Return(1)); + ON_CALL(*bus, GetDAT).WillByDefault(Return(1)); controller.Selection(); EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()) << "There is no device that can be selected"; auto device = make_shared(0); controller.AddDevice(device); - EXPECT_CALL(bus, SetBSY(true)); + EXPECT_CALL(*bus, SetBSY(true)); controller.Selection(); EXPECT_EQ(BUS::phase_t::selection, controller.GetPhase()); } TEST(ScsiControllerTest, Command) { - NiceMock bus; - NiceMock controller(bus, 0); + auto bus = make_shared(); + MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::command); controller.Command(); EXPECT_EQ(BUS::phase_t::command, controller.GetPhase()); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, SetMSG(false)); - EXPECT_CALL(bus, SetCD(true)); - EXPECT_CALL(bus, SetIO(false)); + EXPECT_CALL(*bus, SetMSG(false)); + EXPECT_CALL(*bus, SetCD(true)); + EXPECT_CALL(*bus, SetIO(false)); controller.Command(); EXPECT_EQ(BUS::phase_t::command, controller.GetPhase()); controller.SetPhase(BUS::phase_t::reserved); - ON_CALL(bus, CommandHandShake).WillByDefault(Return(6)); - EXPECT_CALL(bus, SetMSG(false)); - EXPECT_CALL(bus, SetCD(true)); - EXPECT_CALL(bus, SetIO(false)); + ON_CALL(*bus, CommandHandShake).WillByDefault(Return(6)); + EXPECT_CALL(*bus, SetMSG(false)); + EXPECT_CALL(*bus, SetCD(true)); + EXPECT_CALL(*bus, SetIO(false)); EXPECT_CALL(controller, Execute); controller.Command(); EXPECT_EQ(BUS::phase_t::command, controller.GetPhase()); @@ -167,13 +167,13 @@ TEST(ScsiControllerTest, Command) TEST(ScsiControllerTest, MsgIn) { - NiceMock bus; + auto bus = make_shared(); MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, SetMSG(true)); - EXPECT_CALL(bus, SetCD(true)); - EXPECT_CALL(bus, SetIO(true)); + EXPECT_CALL(*bus, SetMSG(true)); + EXPECT_CALL(*bus, SetCD(true)); + EXPECT_CALL(*bus, SetIO(true)); controller.MsgIn(); EXPECT_EQ(BUS::phase_t::msgin, controller.GetPhase()); EXPECT_FALSE(controller.HasValidLength()); @@ -182,13 +182,13 @@ TEST(ScsiControllerTest, MsgIn) TEST(ScsiControllerTest, MsgOut) { - NiceMock bus; + auto bus = make_shared(); MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, SetMSG(true)); - EXPECT_CALL(bus, SetCD(true)); - EXPECT_CALL(bus, SetIO(false)); + EXPECT_CALL(*bus, SetMSG(true)); + EXPECT_CALL(*bus, SetCD(true)); + EXPECT_CALL(*bus, SetIO(false)); controller.MsgOut(); EXPECT_EQ(BUS::phase_t::msgout, controller.GetPhase()); EXPECT_EQ(1, controller.GetLength()); @@ -197,7 +197,7 @@ TEST(ScsiControllerTest, MsgOut) TEST(ScsiControllerTest, DataIn) { - NiceMock bus; + auto bus = make_shared(); MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::reserved); @@ -207,9 +207,9 @@ TEST(ScsiControllerTest, DataIn) EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()); controller.SetLength(1); - EXPECT_CALL(bus, SetMSG(false)); - EXPECT_CALL(bus, SetCD(false)); - EXPECT_CALL(bus, SetIO(true)); + EXPECT_CALL(*bus, SetMSG(false)); + EXPECT_CALL(*bus, SetCD(false)); + EXPECT_CALL(*bus, SetIO(true)); controller.DataIn(); EXPECT_EQ(BUS::phase_t::datain, controller.GetPhase()); EXPECT_EQ(0, controller.GetOffset()); @@ -217,7 +217,7 @@ TEST(ScsiControllerTest, DataIn) TEST(ScsiControllerTest, DataOut) { - NiceMock bus; + auto bus = make_shared(); MockScsiController controller(bus, 0); controller.SetPhase(BUS::phase_t::reserved); @@ -227,9 +227,9 @@ TEST(ScsiControllerTest, DataOut) EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()); controller.SetLength(1); - EXPECT_CALL(bus, SetMSG(false)); - EXPECT_CALL(bus, SetCD(false)); - EXPECT_CALL(bus, SetIO(false)); + EXPECT_CALL(*bus, SetMSG(false)); + EXPECT_CALL(*bus, SetCD(false)); + EXPECT_CALL(*bus, SetIO(false)); controller.DataOut(); EXPECT_EQ(BUS::phase_t::dataout, controller.GetPhase()); EXPECT_EQ(0, controller.GetOffset()); @@ -237,40 +237,40 @@ TEST(ScsiControllerTest, DataOut) TEST(ScsiControllerTest, Error) { - NiceMock bus; + auto bus = make_shared(); MockScsiController controller(bus, 0); - ON_CALL(bus, GetRST).WillByDefault(Return(true)); + ON_CALL(*bus, GetRST).WillByDefault(Return(true)); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST()); - EXPECT_CALL(bus, Reset); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST()); + EXPECT_CALL(*bus, Reset); EXPECT_CALL(controller, Reset); controller.Error(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION, status::RESERVATION_CONFLICT); EXPECT_EQ(status::GOOD, controller.GetStatus()); EXPECT_EQ(BUS::phase_t::reserved, controller.GetPhase()); - ON_CALL(bus, GetRST).WillByDefault(Return(false)); + ON_CALL(*bus, GetRST).WillByDefault(Return(false)); controller.SetPhase(BUS::phase_t::status); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST()); - EXPECT_CALL(bus, Reset).Times(0); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST()); + EXPECT_CALL(*bus, Reset).Times(0); EXPECT_CALL(controller, Reset).Times(0); controller.Error(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION, status::RESERVATION_CONFLICT); EXPECT_EQ(BUS::phase_t::busfree, controller.GetPhase()); controller.SetPhase(BUS::phase_t::msgin); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST()); - EXPECT_CALL(bus, Reset).Times(0); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST()); + EXPECT_CALL(*bus, Reset).Times(0); EXPECT_CALL(controller, Reset).Times(0); controller.Error(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION, status::RESERVATION_CONFLICT); EXPECT_EQ(BUS::phase_t::busfree, controller.GetPhase()); controller.SetPhase(BUS::phase_t::reserved); - EXPECT_CALL(bus, Acquire); - EXPECT_CALL(bus, GetRST()); - EXPECT_CALL(bus, Reset).Times(0); + EXPECT_CALL(*bus, Acquire); + EXPECT_CALL(*bus, GetRST()); + EXPECT_CALL(*bus, Reset).Times(0); EXPECT_CALL(controller, Reset).Times(0); EXPECT_CALL(controller, Status); controller.Error(sense_key::ABORTED_COMMAND, asc::NO_ADDITIONAL_SENSE_INFORMATION, status::RESERVATION_CONFLICT); @@ -280,7 +280,7 @@ TEST(ScsiControllerTest, Error) TEST(ScsiControllerTest, RequestSense) { - MockScsiController controller; + MockScsiController controller(make_shared()); auto device = make_shared(0); controller.AddDevice(device); diff --git a/src/raspberrypi/test/scsi_daynaport_test.cpp b/src/raspberrypi/test/scsi_daynaport_test.cpp index 4a4de736..c7d7c291 100644 --- a/src/raspberrypi/test/scsi_daynaport_test.cpp +++ b/src/raspberrypi/test/scsi_daynaport_test.cpp @@ -18,7 +18,7 @@ TEST(ScsiDaynaportTest, Inquiry) TEST(ScsiDaynaportTest, Dispatch) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); EXPECT_FALSE(daynaport->Dispatch(scsi_command::eCmdIcd)) << "Command is not supported by this class"; @@ -36,7 +36,7 @@ TEST(ScsiDaynaportTest, Dispatch) TEST(ScsiDaynaportTest, TestUnitReady) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); EXPECT_CALL(controller, Status()); @@ -47,7 +47,7 @@ TEST(ScsiDaynaportTest, TestUnitReady) TEST(ScsiDaynaportTest, Read) { vector buf(0); - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, controller)); vector& cmd = controller.GetCmd(); @@ -60,7 +60,7 @@ TEST(ScsiDaynaportTest, Read) TEST(ScsiDaynaportTest, WriteCheck) { vector buf(0); - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, controller)); EXPECT_THROW(daynaport->WriteCheck(0), scsi_exception); @@ -69,7 +69,7 @@ TEST(ScsiDaynaportTest, WriteCheck) TEST(ScsiDaynaportTest, WriteBytes) { vector buf(0); - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = dynamic_pointer_cast(CreateDevice(SCDP, controller)); vector& cmd = controller.GetCmd(); @@ -81,7 +81,7 @@ TEST(ScsiDaynaportTest, WriteBytes) TEST(ScsiDaynaportTest, Read6) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); @@ -92,7 +92,7 @@ TEST(ScsiDaynaportTest, Read6) TEST(ScsiDaynaportTest, Write6) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); @@ -113,7 +113,7 @@ TEST(ScsiDaynaportTest, Write6) TEST(ScsiDaynaportTest, TestRetrieveStats) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); @@ -126,7 +126,7 @@ TEST(ScsiDaynaportTest, TestRetrieveStats) TEST(ScsiDaynaportTest, SetInterfaceMode) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); @@ -159,7 +159,7 @@ TEST(ScsiDaynaportTest, SetInterfaceMode) TEST(ScsiDaynaportTest, SetMcastAddr) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); @@ -173,7 +173,7 @@ TEST(ScsiDaynaportTest, SetMcastAddr) TEST(ScsiDaynaportTest, EnableInterface) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto daynaport = CreateDevice(SCDP, controller); vector& cmd = controller.GetCmd(); diff --git a/src/raspberrypi/test/scsi_printer_test.cpp b/src/raspberrypi/test/scsi_printer_test.cpp index 6005bd85..8880329d 100644 --- a/src/raspberrypi/test/scsi_printer_test.cpp +++ b/src/raspberrypi/test/scsi_printer_test.cpp @@ -16,7 +16,7 @@ using namespace std; TEST(ScsiPrinterTest, Init) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); unordered_map params; @@ -36,7 +36,7 @@ TEST(ScsiPrinterTest, Dispatch) TEST(ScsiPrinterTest, TestUnitReady) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); EXPECT_CALL(controller, Status()); @@ -51,7 +51,7 @@ TEST(ScsiPrinterTest, Inquiry) TEST(ScsiPrinterTest, ReserveUnit) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); EXPECT_CALL(controller, Status()).Times(1); @@ -61,7 +61,7 @@ TEST(ScsiPrinterTest, ReserveUnit) TEST(ScsiPrinterTest, ReleaseUnit) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); EXPECT_CALL(controller, Status()).Times(1); @@ -71,7 +71,7 @@ TEST(ScsiPrinterTest, ReleaseUnit) TEST(ScsiPrinterTest, SendDiagnostic) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); EXPECT_CALL(controller, Status()).Times(1); @@ -81,7 +81,7 @@ TEST(ScsiPrinterTest, SendDiagnostic) TEST(ScsiPrinterTest, Print) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); vector& cmd = controller.GetCmd(); @@ -96,7 +96,7 @@ TEST(ScsiPrinterTest, Print) TEST(ScsiPrinterTest, StopPrint) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = CreateDevice(SCLP, controller); EXPECT_CALL(controller, Status()); @@ -106,7 +106,7 @@ TEST(ScsiPrinterTest, StopPrint) TEST(ScsiPrinterTest, WriteByteSequence) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto printer = dynamic_pointer_cast(CreateDevice(SCLP, controller)); vector buf(1); diff --git a/src/raspberrypi/test/scsicd_test.cpp b/src/raspberrypi/test/scsicd_test.cpp index 6528564b..732652cb 100644 --- a/src/raspberrypi/test/scsicd_test.cpp +++ b/src/raspberrypi/test/scsicd_test.cpp @@ -39,7 +39,7 @@ TEST(ScsiCdTest, SetUpModePages) TEST(ScsiCdTest, ReadToc) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); const unordered_set sector_sizes; auto cd = make_shared(0, sector_sizes); diff --git a/src/raspberrypi/test/storage_device_test.cpp b/src/raspberrypi/test/storage_device_test.cpp index d8626db2..87a46b4c 100644 --- a/src/raspberrypi/test/storage_device_test.cpp +++ b/src/raspberrypi/test/storage_device_test.cpp @@ -140,7 +140,7 @@ TEST(StorageDeviceTest, GetFileSize) TEST(StorageDeviceTest, Dispatch) { - MockAbstractController controller(0); + MockAbstractController controller(make_shared(), 0); auto device = make_shared>(); controller.AddDevice(device); diff --git a/src/raspberrypi/test/test_shared.cpp b/src/raspberrypi/test/test_shared.cpp index 65babd0d..5addf1f7 100644 --- a/src/raspberrypi/test/test_shared.cpp +++ b/src/raspberrypi/test/test_shared.cpp @@ -21,7 +21,7 @@ shared_ptr CreateDevice(PbDeviceType type, MockAbstractController { DeviceFactory device_factory; auto bus = make_shared(); - auto controller_manager = make_shared(*bus); + auto controller_manager = make_shared(bus); auto device = device_factory.CreateDevice(*controller_manager, type, 0, extension); @@ -33,7 +33,7 @@ shared_ptr CreateDevice(PbDeviceType type, MockAbstractController void TestInquiry(PbDeviceType type, device_type t, scsi_level l, const string& ident, int additional_length, bool removable, const string& extension) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = CreateDevice(type, controller, extension); vector& cmd = controller.GetCmd(); @@ -62,7 +62,7 @@ void TestInquiry(PbDeviceType type, device_type t, scsi_level l, const string& i void TestDispatch(PbDeviceType type) { - NiceMock controller(0); + NiceMock controller(make_shared(), 0); auto device = CreateDevice(type, controller); EXPECT_FALSE(device->Dispatch(scsi_command::eCmdIcd)) << "Command is not supported by this class";