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:
akuker 2022-10-24 19:21:40 -05:00 committed by GitHub
parent 73ecd4d1b8
commit ea8bc3970d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 3535 additions and 2050 deletions

3
.gitignore vendored
View File

@ -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

View 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

View File

@ -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
}
]
},
]
}
}

View File

@ -9,6 +9,8 @@
"ratio": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp"
"utility": "cpp",
"cstdint": "cpp",
"stdexcept": "cpp"
}
}

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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
};

View File

@ -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

View 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

View 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
};

View 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>();
}
}

View 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();
};

View File

@ -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

View File

@ -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

View 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__
}

View 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
};

View File

@ -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

View 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

View 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);
};

View File

@ -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);
}

View File

@ -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;
};

View 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)
;
}

View 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;
};

View 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)
;
}

View 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;
};

View File

@ -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);

View File

@ -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);

View File

@ -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)
{

View File

@ -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());

View File

@ -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, "");

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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";