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