mirror of
https://github.com/akuker/RASCSI.git
synced 2025-04-06 07:38:10 +00:00
Architectural updates for future support of Banana Pi (#928)
* Added logic to figure out what type of host we're running on - Banana Pi or Raspberry Pi * Split out the raspberry pi logic to separate classes that are created at start-up based upon the host configuration * Added System Timer class for Allwinner H3 CPU * Added stubs for GPIO BUS for Allwinner H3 CPU Authored-by: Tony Kuker <akuker@gmail.com>
This commit is contained in:
parent
73ecd4d1b8
commit
ea8bc3970d
.gitignore
src/raspberrypi
.clang-format
.vscode
Makefilecontrollers
hal
gpiobus.cppgpiobus.hgpiobus_aibom.hgpiobus_allwinner.cppgpiobus_allwinner.hgpiobus_factory.cppgpiobus_factory.hgpiobus_fullspec.hgpiobus_gamernium.hgpiobus_raspberry.cppgpiobus_raspberry.hgpiobus_standard.hsbc_version.cppsbc_version.hsystimer.cppsystimer.hsystimer_allwinner.cppsystimer_allwinner.hsystimer_raspberry.cppsystimer_raspberry.h
rascsi.cpprasdump.cppscsimon.cpptest
abstract_controller_test.cppcontroller_manager_test.cppdevice_factory_test.cppdisk_test.cpphost_services_test.cppmocks.hmode_page_device_test.cppprimary_device_test.cpprascsi_executor_test.cpprascsi_response_test.cppscsi_controller_test.cppscsi_daynaport_test.cppscsi_printer_test.cppscsicd_test.cppstorage_device_test.cpptest_shared.cpp
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||
|
11
src/raspberrypi/.clang-format
Normal file
11
src/raspberrypi/.clang-format
Normal file
@ -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
|
30
src/raspberrypi/.vscode/launch.json
vendored
30
src/raspberrypi/.vscode/launch.json
vendored
@ -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
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
4
src/raspberrypi/.vscode/settings.json
vendored
4
src/raspberrypi/.vscode/settings.json
vendored
@ -9,6 +9,8 @@
|
||||
"ratio": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp"
|
||||
"utility": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"stdexcept": "cpp"
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -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> 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> bus;
|
||||
|
||||
int max_luns;
|
||||
|
||||
|
@ -23,13 +23,13 @@ class PrimaryDevice;
|
||||
|
||||
class ControllerManager
|
||||
{
|
||||
BUS& bus;
|
||||
std::shared_ptr<BUS> bus;
|
||||
|
||||
unordered_map<int, shared_ptr<AbstractController>> controllers;
|
||||
|
||||
public:
|
||||
|
||||
explicit ControllerManager(BUS& bus) : bus(bus) {}
|
||||
explicit ControllerManager(std::shared_ptr<BUS> bus) : bus(bus) {}
|
||||
~ControllerManager() = default;
|
||||
|
||||
// Maximum number of controller devices
|
||||
|
@ -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> 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);
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
// Maximum number of logical units
|
||||
static const int LUN_MAX = 32;
|
||||
|
||||
ScsiController(BUS&, int);
|
||||
ScsiController(shared_ptr<BUS>, int);
|
||||
~ScsiController() override = default;
|
||||
|
||||
void Reset() override;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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<<PIN_DT0)|\
|
||||
(1<<PIN_DT1)|\
|
||||
(1<<PIN_DT2)|\
|
||||
(1<<PIN_DT3)|\
|
||||
(1<<PIN_DT4)|\
|
||||
(1<<PIN_DT5)|\
|
||||
(1<<PIN_DT6)|\
|
||||
(1<<PIN_DT7)|\
|
||||
(1<<PIN_DP)|\
|
||||
(1<<PIN_ATN)|\
|
||||
(1<<PIN_RST)|\
|
||||
(1<<PIN_ACK)|\
|
||||
(1<<PIN_REQ)|\
|
||||
(1<<PIN_MSG)|\
|
||||
(1<<PIN_CD)|\
|
||||
(1<<PIN_IO)|\
|
||||
(1<<PIN_BSY)|\
|
||||
(1<<PIN_SEL))
|
||||
#define ALL_SCSI_PINS \
|
||||
((1 << PIN_DT0) | (1 << PIN_DT1) | (1 << PIN_DT2) | (1 << PIN_DT3) | (1 << PIN_DT4) | (1 << PIN_DT5) | \
|
||||
(1 << PIN_DT6) | (1 << PIN_DT7) | (1 << PIN_DP) | (1 << PIN_ATN) | (1 << PIN_RST) | (1 << PIN_ACK) | \
|
||||
(1 << PIN_REQ) | (1 << PIN_MSG) | (1 << PIN_CD) | (1 << PIN_IO) | (1 << PIN_BSY) | (1 << PIN_SEL))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GPIO)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static uint32_t SYST_OFFSET = 0x00003000;
|
||||
const static uint32_t IRPT_OFFSET = 0x0000B200;
|
||||
const static uint32_t ARMT_OFFSET = 0x0000B400;
|
||||
const static uint32_t PADS_OFFSET = 0x00100000;
|
||||
const static uint32_t GPIO_OFFSET = 0x00200000;
|
||||
const static uint32_t QA7_OFFSET = 0x01000000;
|
||||
const static uint32_t SYST_OFFSET = 0x00003000;
|
||||
const static uint32_t IRPT_OFFSET = 0x0000B200;
|
||||
const static uint32_t ARMT_OFFSET = 0x0000B400;
|
||||
const static uint32_t PADS_OFFSET = 0x00100000;
|
||||
const static uint32_t GPIO_OFFSET = 0x00200000;
|
||||
const static uint32_t QA7_OFFSET = 0x01000000;
|
||||
|
||||
const static int GPIO_INPUT = 0;
|
||||
const static int GPIO_OUTPUT = 1;
|
||||
const static int GPIO_PULLNONE = 0;
|
||||
const static int GPIO_PULLDOWN = 1;
|
||||
const static int GPIO_PULLUP = 2;
|
||||
const static int GPIO_FSEL_0 = 0;
|
||||
const static int GPIO_FSEL_1 = 1;
|
||||
const static int GPIO_FSEL_2 = 2;
|
||||
const static int GPIO_FSEL_3 = 3;
|
||||
const static int GPIO_SET_0 = 7;
|
||||
const static int GPIO_CLR_0 = 10;
|
||||
const static int GPIO_LEV_0 = 13;
|
||||
const static int GPIO_EDS_0 = 16;
|
||||
const static int GPIO_REN_0 = 19;
|
||||
const static int GPIO_FEN_0 = 22;
|
||||
const static int GPIO_HEN_0 = 25;
|
||||
const static int GPIO_LEN_0 = 28;
|
||||
const static int GPIO_AREN_0 = 31;
|
||||
const static int GPIO_AFEN_0 = 34;
|
||||
const static int GPIO_PUD = 37;
|
||||
const static int GPIO_CLK_0 = 38;
|
||||
const static int GPIO_GPPINMUXSD = 52;
|
||||
const static int GPIO_PUPPDN0 = 57;
|
||||
const static int GPIO_PUPPDN1 = 58;
|
||||
const static int GPIO_PUPPDN3 = 59;
|
||||
const static int GPIO_PUPPDN4 = 60;
|
||||
const static int PAD_0_27 = 11;
|
||||
const static int SYST_CS = 0;
|
||||
const static int SYST_CLO = 1;
|
||||
const static int SYST_CHI = 2;
|
||||
const static int SYST_C0 = 3;
|
||||
const static int SYST_C1 = 4;
|
||||
const static int SYST_C2 = 5;
|
||||
const static int SYST_C3 = 6;
|
||||
const static int ARMT_LOAD = 0;
|
||||
const static int ARMT_VALUE = 1;
|
||||
const static int ARMT_CTRL = 2;
|
||||
const static int ARMT_CLRIRQ = 3;
|
||||
const static int ARMT_RAWIRQ = 4;
|
||||
const static int ARMT_MSKIRQ = 5;
|
||||
const static int ARMT_RELOAD = 6;
|
||||
const static int ARMT_PREDIV = 7;
|
||||
const static int ARMT_FREERUN = 8;
|
||||
const static int IRPT_PND_IRQ_B = 0;
|
||||
const static int IRPT_PND_IRQ_1 = 1;
|
||||
const static int IRPT_PND_IRQ_2 = 2;
|
||||
const static int IRPT_FIQ_CNTL = 3;
|
||||
const static int IRPT_ENB_IRQ_1 = 4;
|
||||
const static int IRPT_ENB_IRQ_2 = 5;
|
||||
const static int IRPT_ENB_IRQ_B = 6;
|
||||
const static int IRPT_DIS_IRQ_1 = 7;
|
||||
const static int IRPT_DIS_IRQ_2 = 8;
|
||||
const static int IRPT_DIS_IRQ_B = 9;
|
||||
const static int QA7_CORE0_TINTC = 16;
|
||||
const static int GPIO_IRQ = (32 + 20); // GPIO3
|
||||
const static int GPIO_INPUT = 0;
|
||||
const static int GPIO_OUTPUT = 1;
|
||||
const static int GPIO_PULLNONE = 0;
|
||||
const static int GPIO_PULLDOWN = 1;
|
||||
const static int GPIO_PULLUP = 2;
|
||||
const static int GPIO_FSEL_0 = 0;
|
||||
const static int GPIO_FSEL_1 = 1;
|
||||
const static int GPIO_FSEL_2 = 2;
|
||||
const static int GPIO_FSEL_3 = 3;
|
||||
const static int GPIO_SET_0 = 7;
|
||||
const static int GPIO_CLR_0 = 10;
|
||||
const static int GPIO_LEV_0 = 13;
|
||||
const static int GPIO_EDS_0 = 16;
|
||||
const static int GPIO_REN_0 = 19;
|
||||
const static int GPIO_FEN_0 = 22;
|
||||
const static int GPIO_HEN_0 = 25;
|
||||
const static int GPIO_LEN_0 = 28;
|
||||
const static int GPIO_AREN_0 = 31;
|
||||
const static int GPIO_AFEN_0 = 34;
|
||||
const static int GPIO_PUD = 37;
|
||||
const static int GPIO_CLK_0 = 38;
|
||||
const static int GPIO_GPPINMUXSD = 52;
|
||||
const static int GPIO_PUPPDN0 = 57;
|
||||
const static int GPIO_PUPPDN1 = 58;
|
||||
const static int GPIO_PUPPDN3 = 59;
|
||||
const static int GPIO_PUPPDN4 = 60;
|
||||
const static int PAD_0_27 = 11;
|
||||
const static int SYST_CS = 0;
|
||||
const static int SYST_CLO = 1;
|
||||
const static int SYST_CHI = 2;
|
||||
const static int SYST_C0 = 3;
|
||||
const static int SYST_C1 = 4;
|
||||
const static int SYST_C2 = 5;
|
||||
const static int SYST_C3 = 6;
|
||||
const static int ARMT_LOAD = 0;
|
||||
const static int ARMT_VALUE = 1;
|
||||
const static int ARMT_CTRL = 2;
|
||||
const static int ARMT_CLRIRQ = 3;
|
||||
const static int ARMT_RAWIRQ = 4;
|
||||
const static int ARMT_MSKIRQ = 5;
|
||||
const static int ARMT_RELOAD = 6;
|
||||
const static int ARMT_PREDIV = 7;
|
||||
const static int ARMT_FREERUN = 8;
|
||||
const static int IRPT_PND_IRQ_B = 0;
|
||||
const static int IRPT_PND_IRQ_1 = 1;
|
||||
const static int IRPT_PND_IRQ_2 = 2;
|
||||
const static int IRPT_FIQ_CNTL = 3;
|
||||
const static int IRPT_ENB_IRQ_1 = 4;
|
||||
const static int IRPT_ENB_IRQ_2 = 5;
|
||||
const static int IRPT_ENB_IRQ_B = 6;
|
||||
const static int IRPT_DIS_IRQ_1 = 7;
|
||||
const static int IRPT_DIS_IRQ_2 = 8;
|
||||
const static int IRPT_DIS_IRQ_B = 9;
|
||||
const static int QA7_CORE0_TINTC = 16;
|
||||
const static int GPIO_IRQ = (32 + 20); // GPIO3
|
||||
|
||||
#define GPIO_INEDGE ((1 << PIN_BSY) | \
|
||||
(1 << PIN_SEL) | \
|
||||
(1 << PIN_ATN) | \
|
||||
(1 << PIN_ACK) | \
|
||||
(1 << PIN_RST))
|
||||
#define GPIO_INEDGE ((1 << PIN_BSY) | (1 << PIN_SEL) | (1 << PIN_ATN) | (1 << PIN_ACK) | (1 << PIN_RST))
|
||||
|
||||
#define GPIO_MCI ((1 << PIN_MSG) | \
|
||||
(1 << PIN_CD) | \
|
||||
(1 << PIN_IO))
|
||||
#define GPIO_MCI ((1 << PIN_MSG) | (1 << PIN_CD) | (1 << PIN_IO))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GIC)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static uint32_t ARM_GICD_BASE = 0xFF841000;
|
||||
const static uint32_t ARM_GICC_BASE = 0xFF842000;
|
||||
const static uint32_t ARM_GIC_END = 0xFF847FFF;
|
||||
const static int GICD_CTLR = 0x000;
|
||||
const static int GICD_IGROUPR0 = 0x020;
|
||||
const static int GICD_ISENABLER0 = 0x040;
|
||||
const static int GICD_ICENABLER0 = 0x060;
|
||||
const static int GICD_ISPENDR0 = 0x080;
|
||||
const static int GICD_ICPENDR0 = 0x0A0;
|
||||
const static int GICD_ISACTIVER0 = 0x0C0;
|
||||
const static int GICD_ICACTIVER0 = 0x0E0;
|
||||
const static int GICD_IPRIORITYR0 = 0x100;
|
||||
const static int GICD_ITARGETSR0 = 0x200;
|
||||
const static int GICD_ICFGR0 = 0x300;
|
||||
const static int GICD_SGIR = 0x3C0;
|
||||
const static int GICC_CTLR = 0x000;
|
||||
const static int GICC_PMR = 0x001;
|
||||
const static int GICC_IAR = 0x003;
|
||||
const static int GICC_EOIR = 0x004;
|
||||
const static uint32_t ARM_GICD_BASE = 0xFF841000;
|
||||
const static uint32_t ARM_GICC_BASE = 0xFF842000;
|
||||
const static uint32_t ARM_GIC_END = 0xFF847FFF;
|
||||
const static int GICD_CTLR = 0x000;
|
||||
const static int GICD_IGROUPR0 = 0x020;
|
||||
const static int GICD_ISENABLER0 = 0x040;
|
||||
const static int GICD_ICENABLER0 = 0x060;
|
||||
const static int GICD_ISPENDR0 = 0x080;
|
||||
const static int GICD_ICPENDR0 = 0x0A0;
|
||||
const static int GICD_ISACTIVER0 = 0x0C0;
|
||||
const static int GICD_ICACTIVER0 = 0x0E0;
|
||||
const static int GICD_IPRIORITYR0 = 0x100;
|
||||
const static int GICD_ITARGETSR0 = 0x200;
|
||||
const static int GICD_ICFGR0 = 0x300;
|
||||
const static int GICD_SGIR = 0x3C0;
|
||||
const static int GICC_CTLR = 0x000;
|
||||
const static int GICC_PMR = 0x001;
|
||||
const static int GICC_IAR = 0x003;
|
||||
const static int GICC_EOIR = 0x004;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GIC IRQ)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static int GIC_IRQLOCAL0 = (16 + 14);
|
||||
const static int GIC_GPIO_IRQ = (32 + 116); // GPIO3
|
||||
const static int GIC_IRQLOCAL0 = (16 + 14);
|
||||
const static int GIC_GPIO_IRQ = (32 + 116); // GPIO3
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (Control signals)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define ACT_OFF !ACT_ON
|
||||
#define ENB_OFF !ENB_ON
|
||||
#define TAD_OUT !TAD_IN
|
||||
#define IND_OUT !IND_IN
|
||||
#define DTD_OUT !DTD_IN
|
||||
#define ACT_OFF !ACT_ON
|
||||
#define ENB_OFF !ENB_ON
|
||||
#define TAD_OUT !TAD_IN
|
||||
#define IND_OUT !IND_IN
|
||||
#define DTD_OUT !DTD_IN
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (SCSI)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define IN GPIO_INPUT
|
||||
#define OUT GPIO_OUTPUT
|
||||
const static int ON = 1;
|
||||
const static int OFF = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (bus control timing)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// SCSI Bus timings taken from:
|
||||
// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html
|
||||
const static int SCSI_DELAY_ARBITRATION_DELAY_NS = 2400;
|
||||
const static int SCSI_DELAY_ASSERTION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_BUS_CLEAR_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_FREE_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_SET_DELAY_NS = 1800;
|
||||
const static int SCSI_DELAY_BUS_SETTLE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_CABLE_SKEW_DELAY_NS = 10;
|
||||
const static int SCSI_DELAY_DATA_RELEASE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_DESKEW_DELAY_NS = 45;
|
||||
const static int SCSI_DELAY_DISCONNECTION_DELAY_US = 200;
|
||||
const static int SCSI_DELAY_HOLD_TIME_NS = 45;
|
||||
const static int SCSI_DELAY_NEGATION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S = 10; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_TO_SELECTION_TIME_US = 250*1000; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_HOLD_TIME_US = 25;
|
||||
const static int SCSI_DELAY_SELECTION_ABORT_TIME_US = 200;
|
||||
const static int SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS = 250*1000; // (recommended)
|
||||
const static int SCSI_DELAY_FAST_ASSERTION_PERIOD_NS = 30;
|
||||
const static int SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS = 5;
|
||||
const static int SCSI_DELAY_FAST_DESKEW_DELAY_NS = 20;
|
||||
const static int SCSI_DELAY_FAST_HOLD_TIME_NS = 10;
|
||||
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;
|
||||
#define IN GPIO_INPUT
|
||||
#define OUT GPIO_OUTPUT
|
||||
const static int ON = 1;
|
||||
const static int OFF = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Class definition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class GPIOBUS final : public BUS
|
||||
class GPIOBUS : public BUS
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
GPIOBUS()= default;
|
||||
~GPIOBUS() override = default;
|
||||
// Destructor
|
||||
bool Init(mode_e mode = mode_e::TARGET) override;
|
||||
// Initialization
|
||||
void Reset() override;
|
||||
// Reset
|
||||
void Cleanup() override;
|
||||
// Cleanup
|
||||
public:
|
||||
static GPIOBUS *create();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Bus signal acquisition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
inline uint32_t Acquire() override
|
||||
{
|
||||
#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;
|
||||
// Basic Functions
|
||||
GPIOBUS() = default;
|
||||
~GPIOBUS() override = default;
|
||||
// Destructor
|
||||
bool Init(mode_e mode = mode_e::TARGET) override;
|
||||
// Initialization
|
||||
void Reset() override;
|
||||
// Reset
|
||||
void Cleanup() override;
|
||||
// Cleanup
|
||||
|
||||
#if SIGNAL_CONTROL_MODE < 2
|
||||
// Invert if negative logic (internal processing is unified to positive logic)
|
||||
signals = ~signals;
|
||||
#endif // SIGNAL_CONTROL_MODE
|
||||
uint32_t Acquire() override = 0;
|
||||
|
||||
return signals;
|
||||
#endif // ifdef __x86_64__ || __X86__
|
||||
}
|
||||
void SetENB(bool ast);
|
||||
// Set ENB signal
|
||||
|
||||
void SetENB(bool ast);
|
||||
// Set ENB signal
|
||||
bool GetBSY() const override;
|
||||
// Get BSY signal
|
||||
void SetBSY(bool ast) override;
|
||||
// Set BSY signal
|
||||
|
||||
bool GetBSY() const override;
|
||||
// Get BSY signal
|
||||
void SetBSY(bool ast) override;
|
||||
// Set BSY signal
|
||||
bool GetSEL() const override;
|
||||
// Get SEL signal
|
||||
void SetSEL(bool ast) override;
|
||||
// Set SEL signal
|
||||
|
||||
bool GetSEL() const override;
|
||||
// Get SEL signal
|
||||
void SetSEL(bool ast) override;
|
||||
// Set SEL signal
|
||||
bool GetATN() const override;
|
||||
// Get ATN signal
|
||||
void SetATN(bool ast) override;
|
||||
// Set ATN signal
|
||||
|
||||
bool GetATN() const override;
|
||||
// Get ATN signal
|
||||
void SetATN(bool ast) override;
|
||||
// Set ATN signal
|
||||
bool GetACK() const override;
|
||||
// Get ACK signal
|
||||
void SetACK(bool ast) override;
|
||||
// Set ACK signal
|
||||
|
||||
bool GetACK() const override;
|
||||
// Get ACK signal
|
||||
void SetACK(bool ast) override;
|
||||
// Set ACK signal
|
||||
bool GetACT() const;
|
||||
// Get ACT signal
|
||||
void SetACT(bool ast);
|
||||
// Set ACT signal
|
||||
|
||||
bool GetACT() const;
|
||||
// Get ACT signal
|
||||
void SetACT(bool ast);
|
||||
// Set ACT signal
|
||||
bool GetRST() const override;
|
||||
// Get RST signal
|
||||
void SetRST(bool ast) override;
|
||||
// Set RST signal
|
||||
|
||||
bool GetRST() const override;
|
||||
// Get RST signal
|
||||
void SetRST(bool ast) override;
|
||||
// Set RST signal
|
||||
bool GetMSG() const override;
|
||||
// Get MSG signal
|
||||
void SetMSG(bool ast) override;
|
||||
// Set MSG signal
|
||||
|
||||
bool GetMSG() const override;
|
||||
// Get MSG signal
|
||||
void SetMSG(bool ast) override;
|
||||
// Set MSG signal
|
||||
bool GetCD() const override;
|
||||
// Get CD signal
|
||||
void SetCD(bool ast) override;
|
||||
// Set CD signal
|
||||
|
||||
bool GetCD() const override;
|
||||
// Get CD signal
|
||||
void SetCD(bool ast) override;
|
||||
// Set CD signal
|
||||
bool GetIO() override;
|
||||
// Get IO signal
|
||||
void SetIO(bool ast) override;
|
||||
// Set IO signal
|
||||
|
||||
bool GetIO() override;
|
||||
// Get IO signal
|
||||
void SetIO(bool ast) override;
|
||||
// Set IO signal
|
||||
bool GetREQ() const override;
|
||||
// Get REQ signal
|
||||
void SetREQ(bool ast) override;
|
||||
// Set REQ signal
|
||||
bool GetDP() const override;
|
||||
// Get Data parity signal
|
||||
int CommandHandShake(BYTE *buf) override;
|
||||
// Command receive handshake
|
||||
int ReceiveHandShake(BYTE *buf, int count) override;
|
||||
// Data receive handshake
|
||||
int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override;
|
||||
// Data transmission handshake
|
||||
|
||||
bool GetREQ() const override;
|
||||
// Get REQ signal
|
||||
void SetREQ(bool ast) override;
|
||||
// Set REQ signal
|
||||
static BUS::phase_t GetPhaseRaw(uint32_t raw_data);
|
||||
// Get the phase based on raw data
|
||||
|
||||
BYTE GetDAT() override;
|
||||
// Get DAT signal
|
||||
void SetDAT(BYTE dat) override;
|
||||
// Set DAT signal
|
||||
bool GetDP() const override;
|
||||
// Get Data parity signal
|
||||
int CommandHandShake(BYTE *buf) override;
|
||||
// Command receive handshake
|
||||
int ReceiveHandShake(BYTE *buf, int count) override;
|
||||
// Data receive handshake
|
||||
int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override;
|
||||
// Data transmission handshake
|
||||
|
||||
static BUS::phase_t GetPhaseRaw(DWORD raw_data);
|
||||
// Get the phase based on raw data
|
||||
|
||||
static int GetCommandByteCount(BYTE opcode);
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
// SEL signal interrupt
|
||||
bool PollSelectEvent();
|
||||
// SEL signal event polling
|
||||
void ClearSelectEvent();
|
||||
// Clear SEL signal event
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
private:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable();
|
||||
// Create work data
|
||||
void SetControl(int pin, bool ast);
|
||||
// Set Control Signal
|
||||
void SetMode(int pin, int mode);
|
||||
// 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);
|
||||
// Wait for a signal to change
|
||||
// Interrupt control
|
||||
void DisableIRQ();
|
||||
// IRQ Disabled
|
||||
void EnableIRQ();
|
||||
// IRQ Enabled
|
||||
|
||||
// GPIO pin functionality settings
|
||||
void PinConfig(int pin, int mode);
|
||||
// GPIO pin direction setting
|
||||
void PullConfig(int pin, int mode);
|
||||
// GPIO pin pull up/down resistor setting
|
||||
void PinSetSignal(int pin, bool ast);
|
||||
// Set GPIO output signal
|
||||
void DrvConfig(DWORD drive);
|
||||
// Set GPIO drive strength
|
||||
|
||||
|
||||
mode_e actmode = mode_e::TARGET; // Operation mode
|
||||
|
||||
#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<uint32_t, 4> 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<array<uint32_t, 256>, 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<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
mode_e actmode = mode_e::TARGET; // Operation mode
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
uint32_t baseaddr = 0; // Base address
|
||||
#endif
|
||||
|
||||
static const array<int, 19> SignalTable; // signal table
|
||||
};
|
||||
static const array<int, 19> 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<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#endif
|
||||
};
|
||||
|
@ -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
|
||||
|
120
src/raspberrypi/hal/gpiobus_allwinner.cpp
Normal file
120
src/raspberrypi/hal/gpiobus_allwinner.cpp
Normal file
@ -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
|
128
src/raspberrypi/hal/gpiobus_allwinner.h
Normal file
128
src/raspberrypi/hal/gpiobus_allwinner.h
Normal file
@ -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<uint32_t, 4> 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<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#endif
|
||||
};
|
30
src/raspberrypi/hal/gpiobus_factory.cpp
Normal file
30
src/raspberrypi/hal/gpiobus_factory.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Copyright (C) 2022 akuker
|
||||
// [ GPIO bus factory ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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> GPIOBUS_Factory::Create()
|
||||
{
|
||||
if (SBC_Version::IsBananaPi()) {
|
||||
LOGTRACE("Creating GPIOBUS_Allwinner")
|
||||
return make_unique<GPIOBUS_Allwinner>();
|
||||
} else {
|
||||
LOGTRACE("Creating GPIOBUS_Raspberry")
|
||||
return make_unique<GPIOBUS_Raspberry>();
|
||||
}
|
||||
}
|
24
src/raspberrypi/hal/gpiobus_factory.h
Normal file
24
src/raspberrypi/hal/gpiobus_factory.h
Normal file
@ -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 <memory>
|
||||
|
||||
#include "gpiobus.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class GPIOBUS_Factory
|
||||
{
|
||||
public:
|
||||
static unique_ptr<GPIOBUS> Create();
|
||||
};
|
@ -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
|
||||
|
@ -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
|
||||
|
857
src/raspberrypi/hal/gpiobus_raspberry.cpp
Normal file
857
src/raspberrypi/hal/gpiobus_raspberry.cpp
Normal file
@ -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 <sys/mman.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_raspberry.h"
|
||||
#include "hal/systimer.h"
|
||||
#include "log.h"
|
||||
#include "os.h"
|
||||
#include <string.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#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<BYTE, 4> 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<char, 1024> 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<int, 9> pintbl = {PIN_DT0, PIN_DT1, PIN_DT2, PIN_DT3, PIN_DT4, PIN_DT5, PIN_DT6, PIN_DT7, PIN_DP};
|
||||
|
||||
array<bool, 256> 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__
|
||||
}
|
124
src/raspberrypi/hal/gpiobus_raspberry.h
Normal file
124
src/raspberrypi/hal/gpiobus_raspberry.h
Normal file
@ -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<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#endif
|
||||
};
|
@ -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
|
||||
|
215
src/raspberrypi/hal/sbc_version.cpp
Normal file
215
src/raspberrypi/hal/sbc_version.cpp
Normal file
@ -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 <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
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<std::string, SBC_Version::sbc_version_type> 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<int>(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<BYTE, 4> 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
|
70
src/raspberrypi/hal/sbc_version.h
Normal file
70
src/raspberrypi/hal/sbc_version.h
Normal file
@ -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 <map>
|
||||
#include <string>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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<std::string, sbc_version_type> m_proc_device_tree_mapping;
|
||||
|
||||
static const std::string m_device_tree_model_path;
|
||||
|
||||
static DWORD GetDeviceTreeRanges(const char *filename, DWORD offset);
|
||||
};
|
@ -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 <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <array>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// 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<PlatformSpecificTimer> 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<uint32_t, 32> 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<SysTimer_Raspberry>();
|
||||
is_raspberry = true;
|
||||
} else if (SBC_Version::IsBananaPi()) {
|
||||
systimer_ptr = make_unique<SysTimer_AllWinner>();
|
||||
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);
|
||||
}
|
||||
|
@ -13,11 +13,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
||||
#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<PlatformSpecificTimer> systimer_ptr;
|
||||
};
|
||||
|
156
src/raspberrypi/hal/systimer_allwinner.cpp
Normal file
156
src/raspberrypi/hal/systimer_allwinner.cpp
Normal file
@ -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 <sys/mman.h>
|
||||
|
||||
#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)
|
||||
;
|
||||
}
|
106
src/raspberrypi/hal/systimer_allwinner.h
Normal file
106
src/raspberrypi/hal/systimer_allwinner.h
Normal file
@ -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 <stdint.h>
|
||||
#include <string>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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;
|
||||
};
|
149
src/raspberrypi/hal/systimer_raspberry.cpp
Normal file
149
src/raspberrypi/hal/systimer_raspberry.cpp
Normal file
@ -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 <memory>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#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<uint32_t, 32> 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)
|
||||
;
|
||||
}
|
49
src/raspberrypi/hal/systimer_raspberry.h
Normal file
49
src/raspberrypi/hal/systimer_raspberry.h
Normal file
@ -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 <stdint.h>
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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;
|
||||
};
|
@ -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<GPIOBUS> 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<ControllerManager> 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<RascsiResponse> rascsi_response;
|
||||
shared_ptr<RascsiExecutor> 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<ControllerManager>(bus);
|
||||
rascsi_response = make_shared<RascsiResponse>(device_factory, *controller_manager, ScsiController::LUN_MAX);
|
||||
executor = make_shared<RascsiExecutor>(*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<PbDevice>& 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<PbImageFile>();
|
||||
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<AbstractController> controller = controller_manager.IdentifyController(id_data);
|
||||
shared_ptr<AbstractController> controller = controller_manager->IdentifyController(id_data);
|
||||
if (controller != nullptr) {
|
||||
initiator_id = controller->ExtractInitiatorId(id_data);
|
||||
|
||||
|
@ -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 <cstring>
|
||||
@ -36,7 +37,7 @@ static const int BUFSIZE = 1024 * 64; // Buffer size of about 64KB
|
||||
// Variable Declaration
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
GPIOBUS bus; // Bus
|
||||
unique_ptr<GPIOBUS> 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);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "os.h"
|
||||
#include "log.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "hal/gpiobus_factory.h"
|
||||
#include "rascsi_version.h"
|
||||
#include <sys/time.h>
|
||||
#include <climits>
|
||||
@ -32,7 +33,7 @@ static const int _MAX_FNAME = 256;
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
static volatile bool running; // Running flag
|
||||
GPIOBUS bus; // GPIO Bus
|
||||
unique_ptr<GPIOBUS> 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)
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ using namespace scsi_defs;
|
||||
|
||||
TEST(AbstractControllerTest, AllocateCmd)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 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<MockBus>(), 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<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -50,7 +50,7 @@ TEST(AbstractControllerTest, Reset)
|
||||
|
||||
TEST(AbstractControllerTest, ByteTransfer)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 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<MockBus>(), 0);
|
||||
|
||||
EXPECT_EQ(32, controller.GetMaxLuns());
|
||||
}
|
||||
|
||||
TEST(AbstractControllerTest, Status)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 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<MockBus>(), 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<MockBus>(), ID);
|
||||
|
||||
auto device1 = make_shared<MockPrimaryDevice>(LUN);
|
||||
auto device2 = make_shared<MockPrimaryDevice>(32);
|
||||
auto device3 = make_shared<MockPrimaryDevice>(-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<MockBus>(), 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<MockBus>(), 0);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
|
||||
@ -166,7 +167,7 @@ TEST(AbstractControllerTest, GetLun)
|
||||
{
|
||||
const int LUN = 3;
|
||||
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
|
||||
@ -176,7 +177,7 @@ TEST(AbstractControllerTest, GetLun)
|
||||
|
||||
TEST(AbstractControllerTest, SetLength)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
|
||||
EXPECT_FALSE(controller.HasValidLength());
|
||||
|
||||
@ -187,7 +188,7 @@ TEST(AbstractControllerTest, SetLength)
|
||||
|
||||
TEST(AbstractControllerTest, UpdateOffsetAndLength)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
|
||||
EXPECT_FALSE(controller.HasValidLength());
|
||||
|
||||
@ -197,7 +198,7 @@ TEST(AbstractControllerTest, UpdateOffsetAndLength)
|
||||
|
||||
TEST(AbstractControllerTest, Offset)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
|
||||
controller.ResetOffset();
|
||||
EXPECT_EQ(0, controller.GetOffset());
|
||||
|
@ -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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
ControllerManager controller_manager(bus_ptr);
|
||||
DeviceFactory device_factory;
|
||||
|
||||
auto device = device_factory.CreateDevice(controller_manager, SCHS, 0, "");
|
||||
|
@ -122,9 +122,9 @@ TEST(DeviceFactoryTest, GetDefaultParams)
|
||||
|
||||
TEST(DeviceFactoryTest, UnknownDeviceType)
|
||||
{
|
||||
MockBus bus;
|
||||
auto bus_ptr = make_shared<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>();
|
||||
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);
|
||||
|
@ -18,7 +18,7 @@ using namespace scsi_command_util;
|
||||
|
||||
TEST(DiskTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
const unordered_set<uint32_t> sector_sizes;
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
@ -33,7 +33,7 @@ TEST(DiskTest, Dispatch)
|
||||
|
||||
TEST(DiskTest, Rezero)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -50,7 +50,7 @@ TEST(DiskTest, Rezero)
|
||||
|
||||
TEST(DiskTest, FormatUnit)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -72,7 +72,7 @@ TEST(DiskTest, FormatUnit)
|
||||
|
||||
TEST(DiskTest, ReassignBlocks)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -89,7 +89,7 @@ TEST(DiskTest, ReassignBlocks)
|
||||
|
||||
TEST(DiskTest, Seek6)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -114,7 +114,7 @@ TEST(DiskTest, Seek6)
|
||||
|
||||
TEST(DiskTest, Seek10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -139,7 +139,7 @@ TEST(DiskTest, Seek10)
|
||||
|
||||
TEST(DiskTest, ReadCapacity)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -203,7 +203,7 @@ TEST(DiskTest, ReadCapacity)
|
||||
|
||||
TEST(DiskTest, Read6)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -216,7 +216,7 @@ TEST(DiskTest, Read6)
|
||||
|
||||
TEST(DiskTest, Read10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -234,7 +234,7 @@ TEST(DiskTest, Read10)
|
||||
|
||||
TEST(DiskTest, Read16)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -252,7 +252,7 @@ TEST(DiskTest, Read16)
|
||||
|
||||
TEST(DiskTest, Write6)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -265,7 +265,7 @@ TEST(DiskTest, Write6)
|
||||
|
||||
TEST(DiskTest, Write10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -283,7 +283,7 @@ TEST(DiskTest, Write10)
|
||||
|
||||
TEST(DiskTest, Write16)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -301,7 +301,7 @@ TEST(DiskTest, Write16)
|
||||
|
||||
TEST(DiskTest, Verify10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -319,7 +319,7 @@ TEST(DiskTest, Verify10)
|
||||
|
||||
TEST(DiskTest, Verify16)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -337,7 +337,7 @@ TEST(DiskTest, Verify16)
|
||||
|
||||
TEST(DiskTest, ReadLong10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -360,7 +360,7 @@ TEST(DiskTest, ReadLong10)
|
||||
|
||||
TEST(DiskTest, ReadLong16)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -385,7 +385,7 @@ TEST(DiskTest, ReadLong16)
|
||||
|
||||
TEST(DiskTest, WriteLong10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -408,7 +408,7 @@ TEST(DiskTest, WriteLong10)
|
||||
|
||||
TEST(DiskTest, WriteLong16)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -431,7 +431,7 @@ TEST(DiskTest, WriteLong16)
|
||||
|
||||
TEST(DiskTest, StartStopUnit)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
disk->SetRemovable(true);
|
||||
|
||||
@ -481,7 +481,7 @@ TEST(DiskTest, StartStopUnit)
|
||||
|
||||
TEST(DiskTest, PreventAllowMediumRemoval)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -566,7 +566,7 @@ void DiskTest_ValidateCachePage(AbstractController& controller, int offset)
|
||||
|
||||
TEST(DiskTest, ModeSense6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -617,7 +617,7 @@ TEST(DiskTest, ModeSense6)
|
||||
|
||||
TEST(DiskTest, ModeSense10)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -694,7 +694,7 @@ TEST(DiskTest, ModeSense10)
|
||||
|
||||
TEST(DiskTest, SynchronizeCache)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
@ -712,7 +712,7 @@ TEST(DiskTest, SynchronizeCache)
|
||||
|
||||
TEST(DiskTest, ReadDefectData)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto disk = make_shared<MockDisk>();
|
||||
|
||||
controller.AddDevice(disk);
|
||||
|
@ -21,7 +21,7 @@ TEST(HostServicesTest, Dispatch)
|
||||
|
||||
TEST(HostServicesTest, TestUnitReady)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
@ -36,7 +36,7 @@ TEST(HostServicesTest, Inquiry)
|
||||
|
||||
TEST(HostServicesTest, StartStopUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -68,7 +68,7 @@ TEST(HostServicesTest, StartStopUnit)
|
||||
|
||||
TEST(HostServicesTest, ModeSense6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -105,7 +105,7 @@ TEST(HostServicesTest, ModeSense6)
|
||||
|
||||
TEST(HostServicesTest, ModeSense10)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto services = CreateDevice(SCHS, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -142,8 +142,7 @@ TEST(HostServicesTest, ModeSense10)
|
||||
|
||||
TEST(HostServicesTest, SetUpModePages)
|
||||
{
|
||||
MockBus bus;
|
||||
ControllerManager controller_manager(bus);
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
MockHostServices services(0, controller_manager);
|
||||
map<int, vector<byte>> pages;
|
||||
|
||||
|
@ -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<MockBus> 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<int>& 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<MockBus> bus, int target_id) : ScsiController(bus, target_id) {}
|
||||
MockScsiController(shared_ptr<MockBus> bus) : ScsiController(bus, 0) {}
|
||||
~MockScsiController() override = default;
|
||||
|
||||
NiceMock<MockBus> bus;
|
||||
};
|
||||
|
||||
class MockDevice : public Device
|
||||
|
@ -72,7 +72,7 @@ TEST(ModePageDeviceTest, AddVendorPage)
|
||||
|
||||
TEST(ModePageDeviceTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<NiceMock<MockModePageDevice>>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -82,7 +82,7 @@ TEST(ModePageDeviceTest, Dispatch)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSense6)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<NiceMock<MockModePageDevice>>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -93,7 +93,7 @@ TEST(ModePageDeviceTest, ModeSense6)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSense10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<NiceMock<MockModePageDevice>>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -116,7 +116,7 @@ TEST(ModePageDeviceTest, ModeSelect)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSelect6)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockModePageDevice>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -133,7 +133,7 @@ TEST(ModePageDeviceTest, ModeSelect6)
|
||||
|
||||
TEST(ModePageDeviceTest, ModeSelect10)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockModePageDevice>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
|
@ -19,7 +19,7 @@ TEST(PrimaryDeviceTest, GetId)
|
||||
{
|
||||
const int ID = 5;
|
||||
|
||||
MockAbstractController controller(ID);
|
||||
MockAbstractController controller(make_shared<MockBus>(), ID);
|
||||
auto device = make_shared<MockPrimaryDevice>(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<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -47,7 +47,7 @@ TEST(PrimaryDeviceTest, PhaseChange)
|
||||
|
||||
TEST(PrimaryDeviceTest, Reset)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -62,7 +62,7 @@ TEST(PrimaryDeviceTest, Reset)
|
||||
|
||||
TEST(PrimaryDeviceTest, CheckReservation)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -92,7 +92,7 @@ TEST(PrimaryDeviceTest, CheckReservation)
|
||||
|
||||
TEST(PrimaryDeviceTest, ReserveReleaseUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -117,7 +117,7 @@ TEST(PrimaryDeviceTest, ReserveReleaseUnit)
|
||||
|
||||
TEST(PrimaryDeviceTest, DiscardReservation)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -132,7 +132,7 @@ TEST(PrimaryDeviceTest, DiscardReservation)
|
||||
|
||||
TEST(PrimaryDeviceTest, TestUnitReady)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -169,7 +169,7 @@ TEST(PrimaryDeviceTest, TestUnitReady)
|
||||
|
||||
TEST(PrimaryDeviceTest, Inquiry)
|
||||
{
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(0);
|
||||
auto controller = make_shared<NiceMock<MockAbstractController>>(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller->AddDevice(device);
|
||||
@ -231,7 +231,7 @@ TEST(PrimaryDeviceTest, Inquiry)
|
||||
|
||||
TEST(PrimaryDeviceTest, RequestSense)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -251,7 +251,7 @@ TEST(PrimaryDeviceTest, RequestSense)
|
||||
|
||||
TEST(PrimaryDeviceTest, SendDiagnostic)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(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<MockBus>(), 0);
|
||||
auto device1 = make_shared<MockPrimaryDevice>(LUN1);
|
||||
auto device2 = make_shared<MockPrimaryDevice>(LUN2);
|
||||
|
||||
@ -324,7 +324,7 @@ TEST(PrimaryDeviceTest, ReportLuns)
|
||||
|
||||
TEST(PrimaryDeviceTest, UnknownCommand)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
@ -334,7 +334,7 @@ TEST(PrimaryDeviceTest, UnknownCommand)
|
||||
|
||||
TEST(PrimaryDeviceTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<NiceMock<MockPrimaryDevice>>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
|
@ -38,10 +38,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
const int ID = 3;
|
||||
const int LUN = 0;
|
||||
|
||||
MockBus bus;
|
||||
shared_ptr<MockBus> bus_ptr = make_shared<MockBus>();
|
||||
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<MockRascsiExecutor>(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
@ -151,10 +151,10 @@ TEST_F(RascsiExecutorTest, ProcessDeviceCmd)
|
||||
|
||||
TEST_F(RascsiExecutorTest, ProcessCmd)
|
||||
{
|
||||
MockBus bus;
|
||||
shared_ptr<MockBus> 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<MockRascsiExecutor>(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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
RascsiImage rascsi_image;
|
||||
RascsiResponse rascsi_response(device_factory, controller_manager, 32);
|
||||
RascsiExecutor executor(rascsi_response, rascsi_image, device_factory, controller_manager);
|
||||
|
@ -18,8 +18,8 @@ using namespace rascsi_interface;
|
||||
|
||||
TEST(RascsiResponseTest, Operation_Count)
|
||||
{
|
||||
MockBus bus;
|
||||
ControllerManager controller_manager(bus);
|
||||
auto bus_ptr = make_shared<MockBus>();
|
||||
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<MockBus>();
|
||||
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<MockBus>());
|
||||
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<MockBus>();
|
||||
ControllerManager controller_manager(bus_ptr);
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
unordered_set<int> 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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
const unordered_set<int> ids = { 1, 3 };
|
||||
@ -193,8 +189,7 @@ TEST(RascsiResponseTest, GetServerInfo)
|
||||
|
||||
TEST(RascsiResponseTest, GetVersionInfo)
|
||||
{
|
||||
MockBus bus;
|
||||
ControllerManager controller_manager(bus);
|
||||
ControllerManager controller_manager(make_shared<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
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<MockBus>());
|
||||
DeviceFactory device_factory;
|
||||
RascsiResponse response(device_factory, controller_manager, 32);
|
||||
PbResult result;
|
||||
|
@ -18,7 +18,7 @@ TEST(ScsiControllerTest, GetInitiatorId)
|
||||
{
|
||||
const int ID = 2;
|
||||
|
||||
MockScsiController controller;
|
||||
MockScsiController controller(make_shared<MockBus>());
|
||||
|
||||
controller.Process(ID);
|
||||
EXPECT_EQ(ID, controller.GetInitiatorId());
|
||||
@ -28,34 +28,34 @@ TEST(ScsiControllerTest, GetInitiatorId)
|
||||
|
||||
TEST(ScsiControllerTest, Process)
|
||||
{
|
||||
NiceMock<MockBus> bus;
|
||||
MockScsiController controller(bus, 0);
|
||||
auto bus = make_shared<NiceMock<MockBus>>();
|
||||
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<MockBus>());
|
||||
|
||||
controller.SetPhase(BUS::phase_t::busfree);
|
||||
controller.BusFree();
|
||||
@ -86,80 +86,80 @@ TEST(ScsiControllerTest, BusFree)
|
||||
|
||||
TEST(ScsiControllerTest, Selection)
|
||||
{
|
||||
NiceMock<MockBus> bus;
|
||||
NiceMock<MockScsiController> controller(bus, 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockPrimaryDevice>(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<MockBus> bus;
|
||||
NiceMock<MockScsiController> controller(bus, 0);
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus> bus;
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus> bus;
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus> bus;
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus> bus;
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus> bus;
|
||||
auto bus = make_shared<MockBus>();
|
||||
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<MockBus>());
|
||||
auto device = make_shared<MockPrimaryDevice>(0);
|
||||
|
||||
controller.AddDevice(device);
|
||||
|
@ -18,7 +18,7 @@ TEST(ScsiDaynaportTest, Inquiry)
|
||||
|
||||
TEST(ScsiDaynaportTest, Dispatch)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 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<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
@ -47,7 +47,7 @@ TEST(ScsiDaynaportTest, TestUnitReady)
|
||||
TEST(ScsiDaynaportTest, Read)
|
||||
{
|
||||
vector<BYTE> buf(0);
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -60,7 +60,7 @@ TEST(ScsiDaynaportTest, Read)
|
||||
TEST(ScsiDaynaportTest, WriteCheck)
|
||||
{
|
||||
vector<BYTE> buf(0);
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
|
||||
|
||||
EXPECT_THROW(daynaport->WriteCheck(0), scsi_exception);
|
||||
@ -69,7 +69,7 @@ TEST(ScsiDaynaportTest, WriteCheck)
|
||||
TEST(ScsiDaynaportTest, WriteBytes)
|
||||
{
|
||||
vector<BYTE> buf(0);
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = dynamic_pointer_cast<SCSIDaynaPort>(CreateDevice(SCDP, controller));
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -81,7 +81,7 @@ TEST(ScsiDaynaportTest, WriteBytes)
|
||||
|
||||
TEST(ScsiDaynaportTest, Read6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -92,7 +92,7 @@ TEST(ScsiDaynaportTest, Read6)
|
||||
|
||||
TEST(ScsiDaynaportTest, Write6)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -113,7 +113,7 @@ TEST(ScsiDaynaportTest, Write6)
|
||||
|
||||
TEST(ScsiDaynaportTest, TestRetrieveStats)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -126,7 +126,7 @@ TEST(ScsiDaynaportTest, TestRetrieveStats)
|
||||
|
||||
TEST(ScsiDaynaportTest, SetInterfaceMode)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -159,7 +159,7 @@ TEST(ScsiDaynaportTest, SetInterfaceMode)
|
||||
|
||||
TEST(ScsiDaynaportTest, SetMcastAddr)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -173,7 +173,7 @@ TEST(ScsiDaynaportTest, SetMcastAddr)
|
||||
|
||||
TEST(ScsiDaynaportTest, EnableInterface)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto daynaport = CreateDevice(SCDP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
|
@ -16,7 +16,7 @@ using namespace std;
|
||||
|
||||
TEST(ScsiPrinterTest, Init)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
unordered_map<string, string> params;
|
||||
@ -36,7 +36,7 @@ TEST(ScsiPrinterTest, Dispatch)
|
||||
|
||||
TEST(ScsiPrinterTest, TestUnitReady)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
@ -51,7 +51,7 @@ TEST(ScsiPrinterTest, Inquiry)
|
||||
|
||||
TEST(ScsiPrinterTest, ReserveUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
@ -61,7 +61,7 @@ TEST(ScsiPrinterTest, ReserveUnit)
|
||||
|
||||
TEST(ScsiPrinterTest, ReleaseUnit)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
@ -71,7 +71,7 @@ TEST(ScsiPrinterTest, ReleaseUnit)
|
||||
|
||||
TEST(ScsiPrinterTest, SendDiagnostic)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status()).Times(1);
|
||||
@ -81,7 +81,7 @@ TEST(ScsiPrinterTest, SendDiagnostic)
|
||||
|
||||
TEST(ScsiPrinterTest, Print)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
vector<int>& cmd = controller.GetCmd();
|
||||
@ -96,7 +96,7 @@ TEST(ScsiPrinterTest, Print)
|
||||
|
||||
TEST(ScsiPrinterTest, StopPrint)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = CreateDevice(SCLP, controller);
|
||||
|
||||
EXPECT_CALL(controller, Status());
|
||||
@ -106,7 +106,7 @@ TEST(ScsiPrinterTest, StopPrint)
|
||||
|
||||
TEST(ScsiPrinterTest, WriteByteSequence)
|
||||
{
|
||||
NiceMock<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto printer = dynamic_pointer_cast<SCSIPrinter>(CreateDevice(SCLP, controller));
|
||||
|
||||
vector<BYTE> buf(1);
|
||||
|
@ -39,7 +39,7 @@ TEST(ScsiCdTest, SetUpModePages)
|
||||
|
||||
TEST(ScsiCdTest, ReadToc)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
const unordered_set<uint32_t> sector_sizes;
|
||||
auto cd = make_shared<MockSCSICD>(0, sector_sizes);
|
||||
|
||||
|
@ -140,7 +140,7 @@ TEST(StorageDeviceTest, GetFileSize)
|
||||
|
||||
TEST(StorageDeviceTest, Dispatch)
|
||||
{
|
||||
MockAbstractController controller(0);
|
||||
MockAbstractController controller(make_shared<MockBus>(), 0);
|
||||
auto device = make_shared<NiceMock<MockStorageDevice>>();
|
||||
|
||||
controller.AddDevice(device);
|
||||
|
@ -21,7 +21,7 @@ shared_ptr<PrimaryDevice> CreateDevice(PbDeviceType type, MockAbstractController
|
||||
{
|
||||
DeviceFactory device_factory;
|
||||
auto bus = make_shared<MockBus>();
|
||||
auto controller_manager = make_shared<ControllerManager>(*bus);
|
||||
auto controller_manager = make_shared<ControllerManager>(bus);
|
||||
|
||||
auto device = device_factory.CreateDevice(*controller_manager, type, 0, extension);
|
||||
|
||||
@ -33,7 +33,7 @@ shared_ptr<PrimaryDevice> 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<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = CreateDevice(type, controller, extension);
|
||||
|
||||
vector<int>& 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<MockAbstractController> controller(0);
|
||||
NiceMock<MockAbstractController> controller(make_shared<MockBus>(), 0);
|
||||
auto device = CreateDevice(type, controller);
|
||||
|
||||
EXPECT_FALSE(device->Dispatch(scsi_command::eCmdIcd)) << "Command is not supported by this class";
|
||||
|
Loading…
x
Reference in New Issue
Block a user