mirror of
https://github.com/akuker/RASCSI.git
synced 2024-10-16 07:23:55 +00:00
Architectural updates for future support of Banana Pi (#928)
* Added logic to figure out what type of host we're running on - Banana Pi or Raspberry Pi * Split out the raspberry pi logic to separate classes that are created at start-up based upon the host configuration * Added System Timer class for Allwinner H3 CPU * Added stubs for GPIO BUS for Allwinner H3 CPU Authored-by: Tony Kuker <akuker@gmail.com>
This commit is contained in:
parent
73ecd4d1b8
commit
ea8bc3970d
3
.gitignore
vendored
3
.gitignore
vendored
@ -13,6 +13,9 @@ messages.pot
|
||||
messages.mo
|
||||
report.xml
|
||||
|
||||
# Intermediate files from astyle
|
||||
*.orig
|
||||
|
||||
docker/docker-compose.override.yml
|
||||
/docker/volumes/images/*
|
||||
!/docker/volumes/images/.gitkeep
|
||||
|
11
src/raspberrypi/.clang-format
Normal file
11
src/raspberrypi/.clang-format
Normal file
@ -0,0 +1,11 @@
|
||||
BasedOnStyle: Microsoft
|
||||
IndentWidth: 4
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
BreakBeforeBraces: Linux
|
||||
AlignEscapedNewlines: Left
|
||||
AlignTrailingComments: True
|
||||
AllowShortEnumsOnASingleLine: True
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
ColumnLimit: 120
|
30
src/raspberrypi/.vscode/launch.json
vendored
30
src/raspberrypi/.vscode/launch.json
vendored
@ -5,7 +5,7 @@
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"name": "rascsi (gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/fullspec/rascsi",
|
||||
@ -24,6 +24,30 @@
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "rascsi_test (gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/fullspec/rascsi_test",
|
||||
"args": [],
|
||||
"stopAtEntry": true,
|
||||
"cwd": "${fileDirname}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
4
src/raspberrypi/.vscode/settings.json
vendored
4
src/raspberrypi/.vscode/settings.json
vendored
@ -9,6 +9,8 @@
|
||||
"ratio": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp"
|
||||
"utility": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"stdexcept": "cpp"
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
CROSS_COMPILE =
|
||||
|
||||
CXX = $(CROSS_COMPILE)g++
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
RANLIB = $(CROSS_COMPILE)ranlib
|
||||
|
||||
## DEBUG=1 : A Debug build includes the debugger symbols
|
||||
## and disables compiler optimization. Typically,
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
uint32_t length; // Transfer remaining length
|
||||
};
|
||||
|
||||
AbstractController(BUS& bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {}
|
||||
AbstractController(shared_ptr<BUS> bus, int target_id, int max_luns) : target_id(target_id), bus(bus), max_luns(max_luns) {}
|
||||
~AbstractController() override = default;
|
||||
|
||||
virtual void Error(scsi_defs::sense_key, scsi_defs::asc = scsi_defs::asc::NO_ADDITIONAL_SENSE_INFORMATION,
|
||||
@ -108,7 +108,7 @@ private:
|
||||
|
||||
int target_id;
|
||||
|
||||
BUS& bus;
|
||||
shared_ptr<BUS> bus;
|
||||
|
||||
int max_luns;
|
||||
|
||||
|
@ -23,13 +23,13 @@ class PrimaryDevice;
|
||||
|
||||
class ControllerManager
|
||||
{
|
||||
BUS& bus;
|
||||
std::shared_ptr<BUS> bus;
|
||||
|
||||
unordered_map<int, shared_ptr<AbstractController>> controllers;
|
||||
|
||||
public:
|
||||
|
||||
explicit ControllerManager(BUS& bus) : bus(bus) {}
|
||||
explicit ControllerManager(std::shared_ptr<BUS> bus) : bus(bus) {}
|
||||
~ControllerManager() = default;
|
||||
|
||||
// Maximum number of controller devices
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
using namespace scsi_defs;
|
||||
|
||||
ScsiController::ScsiController(BUS& bus, int target_id) : AbstractController(bus, target_id, LUN_MAX)
|
||||
ScsiController::ScsiController(shared_ptr<BUS> bus, int target_id) : AbstractController(bus, target_id, LUN_MAX)
|
||||
{
|
||||
// The initial buffer size will default to either the default buffer size OR
|
||||
// the size of an Ethernet message, whichever is larger.
|
||||
@ -51,17 +51,17 @@ void ScsiController::Reset()
|
||||
BUS::phase_t ScsiController::Process(int id)
|
||||
{
|
||||
// Get bus information
|
||||
bus.Acquire();
|
||||
bus->Acquire();
|
||||
|
||||
// Check to see if the reset signal was asserted
|
||||
if (bus.GetRST()) {
|
||||
if (bus->GetRST()) {
|
||||
LOGWARN("RESET signal received!")
|
||||
|
||||
// Reset the controller
|
||||
Reset();
|
||||
|
||||
// Reset the bus
|
||||
bus.Reset();
|
||||
bus->Reset();
|
||||
|
||||
return GetPhase();
|
||||
}
|
||||
@ -83,7 +83,7 @@ BUS::phase_t ScsiController::Process(int id)
|
||||
LOGERROR("%s Unhandled SCSI error, resetting controller and bus and entering bus free phase", __PRETTY_FUNCTION__)
|
||||
|
||||
Reset();
|
||||
bus.Reset();
|
||||
bus->Reset();
|
||||
|
||||
BusFree();
|
||||
}
|
||||
@ -98,11 +98,11 @@ void ScsiController::BusFree()
|
||||
|
||||
SetPhase(BUS::phase_t::busfree);
|
||||
|
||||
bus.SetREQ(false);
|
||||
bus.SetMSG(false);
|
||||
bus.SetCD(false);
|
||||
bus.SetIO(false);
|
||||
bus.SetBSY(false);
|
||||
bus->SetREQ(false);
|
||||
bus->SetMSG(false);
|
||||
bus->SetCD(false);
|
||||
bus->SetIO(false);
|
||||
bus->SetBSY(false);
|
||||
|
||||
// Initialize status and message
|
||||
SetStatus(status::GOOD);
|
||||
@ -145,7 +145,7 @@ void ScsiController::BusFree()
|
||||
}
|
||||
|
||||
// Move to selection phase
|
||||
if (bus.GetSEL() && !bus.GetBSY()) {
|
||||
if (bus->GetSEL() && !bus->GetBSY()) {
|
||||
Selection();
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ void ScsiController::Selection()
|
||||
{
|
||||
if (!IsSelection()) {
|
||||
// A different device controller was selected
|
||||
if (int id = 1 << GetTargetId(); ((int)bus.GetDAT() & id) == 0) {
|
||||
if (int id = 1 << GetTargetId(); ((int)bus->GetDAT() & id) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -168,14 +168,14 @@ void ScsiController::Selection()
|
||||
SetPhase(BUS::phase_t::selection);
|
||||
|
||||
// Raise BSY and respond
|
||||
bus.SetBSY(true);
|
||||
bus->SetBSY(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Selection completed
|
||||
if (!bus.GetSEL() && bus.GetBSY()) {
|
||||
if (!bus->GetSEL() && bus->GetBSY()) {
|
||||
// Message out phase if ATN=1, otherwise command phase
|
||||
if (bus.GetATN()) {
|
||||
if (bus->GetATN()) {
|
||||
MsgOut();
|
||||
} else {
|
||||
Command();
|
||||
@ -190,11 +190,11 @@ void ScsiController::Command()
|
||||
|
||||
SetPhase(BUS::phase_t::command);
|
||||
|
||||
bus.SetMSG(false);
|
||||
bus.SetCD(true);
|
||||
bus.SetIO(false);
|
||||
bus->SetMSG(false);
|
||||
bus->SetCD(true);
|
||||
bus->SetIO(false);
|
||||
|
||||
const int actual_count = bus.CommandHandShake(GetBuffer().data());
|
||||
const int actual_count = bus->CommandHandShake(GetBuffer().data());
|
||||
const int command_byte_count = GPIOBUS::GetCommandByteCount(GetBuffer()[0]);
|
||||
|
||||
// If not able to receive all, move to the status phase
|
||||
@ -308,9 +308,9 @@ void ScsiController::Status()
|
||||
SetPhase(BUS::phase_t::status);
|
||||
|
||||
// Signal line operated by the target
|
||||
bus.SetMSG(false);
|
||||
bus.SetCD(true);
|
||||
bus.SetIO(true);
|
||||
bus->SetMSG(false);
|
||||
bus->SetCD(true);
|
||||
bus->SetIO(true);
|
||||
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
@ -331,9 +331,9 @@ void ScsiController::MsgIn()
|
||||
|
||||
SetPhase(BUS::phase_t::msgin);
|
||||
|
||||
bus.SetMSG(true);
|
||||
bus.SetCD(true);
|
||||
bus.SetIO(true);
|
||||
bus->SetMSG(true);
|
||||
bus->SetCD(true);
|
||||
bus->SetIO(true);
|
||||
|
||||
ResetOffset();
|
||||
return;
|
||||
@ -358,9 +358,9 @@ void ScsiController::MsgOut()
|
||||
|
||||
SetPhase(BUS::phase_t::msgout);
|
||||
|
||||
bus.SetMSG(true);
|
||||
bus.SetCD(true);
|
||||
bus.SetIO(false);
|
||||
bus->SetMSG(true);
|
||||
bus->SetCD(true);
|
||||
bus->SetIO(false);
|
||||
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
@ -391,9 +391,9 @@ void ScsiController::DataIn()
|
||||
|
||||
SetPhase(BUS::phase_t::datain);
|
||||
|
||||
bus.SetMSG(false);
|
||||
bus.SetCD(false);
|
||||
bus.SetIO(true);
|
||||
bus->SetMSG(false);
|
||||
bus->SetCD(false);
|
||||
bus->SetIO(true);
|
||||
|
||||
ResetOffset();
|
||||
|
||||
@ -422,9 +422,9 @@ void ScsiController::DataOut()
|
||||
SetPhase(BUS::phase_t::dataout);
|
||||
|
||||
// Signal line operated by the target
|
||||
bus.SetMSG(false);
|
||||
bus.SetCD(false);
|
||||
bus.SetIO(false);
|
||||
bus->SetMSG(false);
|
||||
bus->SetCD(false);
|
||||
bus->SetIO(false);
|
||||
|
||||
ResetOffset();
|
||||
return;
|
||||
@ -436,12 +436,12 @@ void ScsiController::DataOut()
|
||||
void ScsiController::Error(sense_key sense_key, asc asc, status status)
|
||||
{
|
||||
// Get bus information
|
||||
bus.Acquire();
|
||||
bus->Acquire();
|
||||
|
||||
// Reset check
|
||||
if (bus.GetRST()) {
|
||||
if (bus->GetRST()) {
|
||||
Reset();
|
||||
bus.Reset();
|
||||
bus->Reset();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -485,8 +485,8 @@ void ScsiController::Error(sense_key sense_key, asc asc, status status)
|
||||
|
||||
void ScsiController::Send()
|
||||
{
|
||||
assert(!bus.GetREQ());
|
||||
assert(bus.GetIO());
|
||||
assert(!bus->GetREQ());
|
||||
assert(bus->GetIO());
|
||||
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Sending handhake with offset " + to_string(GetOffset()) + ", length "
|
||||
@ -494,7 +494,7 @@ void ScsiController::Send()
|
||||
|
||||
// TODO The delay has to be taken from ctrl.unit[lun], but as there are currently no Daynaport drivers for
|
||||
// LUNs other than 0 this work-around works.
|
||||
if (const int len = bus.SendHandShake(GetBuffer().data() + ctrl.offset, ctrl.length,
|
||||
if (const int len = bus->SendHandShake(GetBuffer().data() + ctrl.offset, ctrl.length,
|
||||
HasDeviceForLun(0) ? GetDeviceForLun(0)->GetSendDelay() : 0);
|
||||
len != (int)ctrl.length) {
|
||||
// If you cannot send all, move to status phase
|
||||
@ -581,15 +581,15 @@ void ScsiController::Receive()
|
||||
LOGTRACE("%s",__PRETTY_FUNCTION__)
|
||||
|
||||
// REQ is low
|
||||
assert(!bus.GetREQ());
|
||||
assert(!bus.GetIO());
|
||||
assert(!bus->GetREQ());
|
||||
assert(!bus->GetIO());
|
||||
|
||||
// Length != 0 if received
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length)
|
||||
|
||||
// If not able to receive all, move to status phase
|
||||
if (int len = bus.ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
|
||||
if (int len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
|
||||
len != (int)ctrl.length) {
|
||||
LOGERROR("%s Not able to receive %d bytes of data, only received %d",__PRETTY_FUNCTION__, ctrl.length, len)
|
||||
Error(sense_key::ABORTED_COMMAND);
|
||||
@ -687,14 +687,14 @@ bool ScsiController::XferMsg(int msg)
|
||||
|
||||
void ScsiController::ReceiveBytes()
|
||||
{
|
||||
assert(!bus.GetREQ());
|
||||
assert(!bus.GetIO());
|
||||
assert(!bus->GetREQ());
|
||||
assert(!bus->GetIO());
|
||||
|
||||
if (HasValidLength()) {
|
||||
LOGTRACE("%s Length is %d bytes", __PRETTY_FUNCTION__, ctrl.length)
|
||||
|
||||
// If not able to receive all, move to status phase
|
||||
if (uint32_t len = bus.ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
|
||||
if (uint32_t len = bus->ReceiveHandShake(GetBuffer().data() + GetOffset(), ctrl.length);
|
||||
len != ctrl.length) {
|
||||
LOGERROR("%s Not able to receive %d bytes of data, only received %d",
|
||||
__PRETTY_FUNCTION__, ctrl.length, len)
|
||||
@ -1040,7 +1040,7 @@ void ScsiController::ParseMessage()
|
||||
void ScsiController::ProcessMessage()
|
||||
{
|
||||
// Continue message out phase as long as ATN keeps asserting
|
||||
if (bus.GetATN()) {
|
||||
if (bus->GetATN()) {
|
||||
// Data transfer is 1 byte x 1 block
|
||||
ResetOffset();
|
||||
SetLength(1);
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
// Maximum number of logical units
|
||||
static const int LUN_MAX = 32;
|
||||
|
||||
ScsiController(BUS&, int);
|
||||
ScsiController(shared_ptr<BUS>, int);
|
||||
~ScsiController() override = default;
|
||||
|
||||
void Reset() override;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,7 +41,13 @@
|
||||
#error Invalid connection type or none specified
|
||||
#endif
|
||||
|
||||
using namespace std; //NOSONAR Not relevant for rascsi
|
||||
#ifdef ENABLE_GPIO_TRACE
|
||||
#define GPIO_FUNCTION_TRACE LOGTRACE("%s", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
#define GPIO_FUNCTION_TRACE
|
||||
#endif
|
||||
|
||||
using namespace std; // NOSONAR Not relevant for rascsi
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
@ -117,399 +123,318 @@ using namespace std; //NOSONAR Not relevant for rascsi
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define ALL_SCSI_PINS \
|
||||
((1<<PIN_DT0)|\
|
||||
(1<<PIN_DT1)|\
|
||||
(1<<PIN_DT2)|\
|
||||
(1<<PIN_DT3)|\
|
||||
(1<<PIN_DT4)|\
|
||||
(1<<PIN_DT5)|\
|
||||
(1<<PIN_DT6)|\
|
||||
(1<<PIN_DT7)|\
|
||||
(1<<PIN_DP)|\
|
||||
(1<<PIN_ATN)|\
|
||||
(1<<PIN_RST)|\
|
||||
(1<<PIN_ACK)|\
|
||||
(1<<PIN_REQ)|\
|
||||
(1<<PIN_MSG)|\
|
||||
(1<<PIN_CD)|\
|
||||
(1<<PIN_IO)|\
|
||||
(1<<PIN_BSY)|\
|
||||
(1<<PIN_SEL))
|
||||
#define ALL_SCSI_PINS \
|
||||
((1 << PIN_DT0) | (1 << PIN_DT1) | (1 << PIN_DT2) | (1 << PIN_DT3) | (1 << PIN_DT4) | (1 << PIN_DT5) | \
|
||||
(1 << PIN_DT6) | (1 << PIN_DT7) | (1 << PIN_DP) | (1 << PIN_ATN) | (1 << PIN_RST) | (1 << PIN_ACK) | \
|
||||
(1 << PIN_REQ) | (1 << PIN_MSG) | (1 << PIN_CD) | (1 << PIN_IO) | (1 << PIN_BSY) | (1 << PIN_SEL))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GPIO)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static uint32_t SYST_OFFSET = 0x00003000;
|
||||
const static uint32_t IRPT_OFFSET = 0x0000B200;
|
||||
const static uint32_t ARMT_OFFSET = 0x0000B400;
|
||||
const static uint32_t PADS_OFFSET = 0x00100000;
|
||||
const static uint32_t GPIO_OFFSET = 0x00200000;
|
||||
const static uint32_t QA7_OFFSET = 0x01000000;
|
||||
const static uint32_t SYST_OFFSET = 0x00003000;
|
||||
const static uint32_t IRPT_OFFSET = 0x0000B200;
|
||||
const static uint32_t ARMT_OFFSET = 0x0000B400;
|
||||
const static uint32_t PADS_OFFSET = 0x00100000;
|
||||
const static uint32_t GPIO_OFFSET = 0x00200000;
|
||||
const static uint32_t QA7_OFFSET = 0x01000000;
|
||||
|
||||
const static int GPIO_INPUT = 0;
|
||||
const static int GPIO_OUTPUT = 1;
|
||||
const static int GPIO_PULLNONE = 0;
|
||||
const static int GPIO_PULLDOWN = 1;
|
||||
const static int GPIO_PULLUP = 2;
|
||||
const static int GPIO_FSEL_0 = 0;
|
||||
const static int GPIO_FSEL_1 = 1;
|
||||
const static int GPIO_FSEL_2 = 2;
|
||||
const static int GPIO_FSEL_3 = 3;
|
||||
const static int GPIO_SET_0 = 7;
|
||||
const static int GPIO_CLR_0 = 10;
|
||||
const static int GPIO_LEV_0 = 13;
|
||||
const static int GPIO_EDS_0 = 16;
|
||||
const static int GPIO_REN_0 = 19;
|
||||
const static int GPIO_FEN_0 = 22;
|
||||
const static int GPIO_HEN_0 = 25;
|
||||
const static int GPIO_LEN_0 = 28;
|
||||
const static int GPIO_AREN_0 = 31;
|
||||
const static int GPIO_AFEN_0 = 34;
|
||||
const static int GPIO_PUD = 37;
|
||||
const static int GPIO_CLK_0 = 38;
|
||||
const static int GPIO_GPPINMUXSD = 52;
|
||||
const static int GPIO_PUPPDN0 = 57;
|
||||
const static int GPIO_PUPPDN1 = 58;
|
||||
const static int GPIO_PUPPDN3 = 59;
|
||||
const static int GPIO_PUPPDN4 = 60;
|
||||
const static int PAD_0_27 = 11;
|
||||
const static int SYST_CS = 0;
|
||||
const static int SYST_CLO = 1;
|
||||
const static int SYST_CHI = 2;
|
||||
const static int SYST_C0 = 3;
|
||||
const static int SYST_C1 = 4;
|
||||
const static int SYST_C2 = 5;
|
||||
const static int SYST_C3 = 6;
|
||||
const static int ARMT_LOAD = 0;
|
||||
const static int ARMT_VALUE = 1;
|
||||
const static int ARMT_CTRL = 2;
|
||||
const static int ARMT_CLRIRQ = 3;
|
||||
const static int ARMT_RAWIRQ = 4;
|
||||
const static int ARMT_MSKIRQ = 5;
|
||||
const static int ARMT_RELOAD = 6;
|
||||
const static int ARMT_PREDIV = 7;
|
||||
const static int ARMT_FREERUN = 8;
|
||||
const static int IRPT_PND_IRQ_B = 0;
|
||||
const static int IRPT_PND_IRQ_1 = 1;
|
||||
const static int IRPT_PND_IRQ_2 = 2;
|
||||
const static int IRPT_FIQ_CNTL = 3;
|
||||
const static int IRPT_ENB_IRQ_1 = 4;
|
||||
const static int IRPT_ENB_IRQ_2 = 5;
|
||||
const static int IRPT_ENB_IRQ_B = 6;
|
||||
const static int IRPT_DIS_IRQ_1 = 7;
|
||||
const static int IRPT_DIS_IRQ_2 = 8;
|
||||
const static int IRPT_DIS_IRQ_B = 9;
|
||||
const static int QA7_CORE0_TINTC = 16;
|
||||
const static int GPIO_IRQ = (32 + 20); // GPIO3
|
||||
const static int GPIO_INPUT = 0;
|
||||
const static int GPIO_OUTPUT = 1;
|
||||
const static int GPIO_PULLNONE = 0;
|
||||
const static int GPIO_PULLDOWN = 1;
|
||||
const static int GPIO_PULLUP = 2;
|
||||
const static int GPIO_FSEL_0 = 0;
|
||||
const static int GPIO_FSEL_1 = 1;
|
||||
const static int GPIO_FSEL_2 = 2;
|
||||
const static int GPIO_FSEL_3 = 3;
|
||||
const static int GPIO_SET_0 = 7;
|
||||
const static int GPIO_CLR_0 = 10;
|
||||
const static int GPIO_LEV_0 = 13;
|
||||
const static int GPIO_EDS_0 = 16;
|
||||
const static int GPIO_REN_0 = 19;
|
||||
const static int GPIO_FEN_0 = 22;
|
||||
const static int GPIO_HEN_0 = 25;
|
||||
const static int GPIO_LEN_0 = 28;
|
||||
const static int GPIO_AREN_0 = 31;
|
||||
const static int GPIO_AFEN_0 = 34;
|
||||
const static int GPIO_PUD = 37;
|
||||
const static int GPIO_CLK_0 = 38;
|
||||
const static int GPIO_GPPINMUXSD = 52;
|
||||
const static int GPIO_PUPPDN0 = 57;
|
||||
const static int GPIO_PUPPDN1 = 58;
|
||||
const static int GPIO_PUPPDN3 = 59;
|
||||
const static int GPIO_PUPPDN4 = 60;
|
||||
const static int PAD_0_27 = 11;
|
||||
const static int SYST_CS = 0;
|
||||
const static int SYST_CLO = 1;
|
||||
const static int SYST_CHI = 2;
|
||||
const static int SYST_C0 = 3;
|
||||
const static int SYST_C1 = 4;
|
||||
const static int SYST_C2 = 5;
|
||||
const static int SYST_C3 = 6;
|
||||
const static int ARMT_LOAD = 0;
|
||||
const static int ARMT_VALUE = 1;
|
||||
const static int ARMT_CTRL = 2;
|
||||
const static int ARMT_CLRIRQ = 3;
|
||||
const static int ARMT_RAWIRQ = 4;
|
||||
const static int ARMT_MSKIRQ = 5;
|
||||
const static int ARMT_RELOAD = 6;
|
||||
const static int ARMT_PREDIV = 7;
|
||||
const static int ARMT_FREERUN = 8;
|
||||
const static int IRPT_PND_IRQ_B = 0;
|
||||
const static int IRPT_PND_IRQ_1 = 1;
|
||||
const static int IRPT_PND_IRQ_2 = 2;
|
||||
const static int IRPT_FIQ_CNTL = 3;
|
||||
const static int IRPT_ENB_IRQ_1 = 4;
|
||||
const static int IRPT_ENB_IRQ_2 = 5;
|
||||
const static int IRPT_ENB_IRQ_B = 6;
|
||||
const static int IRPT_DIS_IRQ_1 = 7;
|
||||
const static int IRPT_DIS_IRQ_2 = 8;
|
||||
const static int IRPT_DIS_IRQ_B = 9;
|
||||
const static int QA7_CORE0_TINTC = 16;
|
||||
const static int GPIO_IRQ = (32 + 20); // GPIO3
|
||||
|
||||
#define GPIO_INEDGE ((1 << PIN_BSY) | \
|
||||
(1 << PIN_SEL) | \
|
||||
(1 << PIN_ATN) | \
|
||||
(1 << PIN_ACK) | \
|
||||
(1 << PIN_RST))
|
||||
#define GPIO_INEDGE ((1 << PIN_BSY) | (1 << PIN_SEL) | (1 << PIN_ATN) | (1 << PIN_ACK) | (1 << PIN_RST))
|
||||
|
||||
#define GPIO_MCI ((1 << PIN_MSG) | \
|
||||
(1 << PIN_CD) | \
|
||||
(1 << PIN_IO))
|
||||
#define GPIO_MCI ((1 << PIN_MSG) | (1 << PIN_CD) | (1 << PIN_IO))
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GIC)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static uint32_t ARM_GICD_BASE = 0xFF841000;
|
||||
const static uint32_t ARM_GICC_BASE = 0xFF842000;
|
||||
const static uint32_t ARM_GIC_END = 0xFF847FFF;
|
||||
const static int GICD_CTLR = 0x000;
|
||||
const static int GICD_IGROUPR0 = 0x020;
|
||||
const static int GICD_ISENABLER0 = 0x040;
|
||||
const static int GICD_ICENABLER0 = 0x060;
|
||||
const static int GICD_ISPENDR0 = 0x080;
|
||||
const static int GICD_ICPENDR0 = 0x0A0;
|
||||
const static int GICD_ISACTIVER0 = 0x0C0;
|
||||
const static int GICD_ICACTIVER0 = 0x0E0;
|
||||
const static int GICD_IPRIORITYR0 = 0x100;
|
||||
const static int GICD_ITARGETSR0 = 0x200;
|
||||
const static int GICD_ICFGR0 = 0x300;
|
||||
const static int GICD_SGIR = 0x3C0;
|
||||
const static int GICC_CTLR = 0x000;
|
||||
const static int GICC_PMR = 0x001;
|
||||
const static int GICC_IAR = 0x003;
|
||||
const static int GICC_EOIR = 0x004;
|
||||
const static uint32_t ARM_GICD_BASE = 0xFF841000;
|
||||
const static uint32_t ARM_GICC_BASE = 0xFF842000;
|
||||
const static uint32_t ARM_GIC_END = 0xFF847FFF;
|
||||
const static int GICD_CTLR = 0x000;
|
||||
const static int GICD_IGROUPR0 = 0x020;
|
||||
const static int GICD_ISENABLER0 = 0x040;
|
||||
const static int GICD_ICENABLER0 = 0x060;
|
||||
const static int GICD_ISPENDR0 = 0x080;
|
||||
const static int GICD_ICPENDR0 = 0x0A0;
|
||||
const static int GICD_ISACTIVER0 = 0x0C0;
|
||||
const static int GICD_ICACTIVER0 = 0x0E0;
|
||||
const static int GICD_IPRIORITYR0 = 0x100;
|
||||
const static int GICD_ITARGETSR0 = 0x200;
|
||||
const static int GICD_ICFGR0 = 0x300;
|
||||
const static int GICD_SGIR = 0x3C0;
|
||||
const static int GICC_CTLR = 0x000;
|
||||
const static int GICC_PMR = 0x001;
|
||||
const static int GICC_IAR = 0x003;
|
||||
const static int GICC_EOIR = 0x004;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (GIC IRQ)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
const static int GIC_IRQLOCAL0 = (16 + 14);
|
||||
const static int GIC_GPIO_IRQ = (32 + 116); // GPIO3
|
||||
const static int GIC_IRQLOCAL0 = (16 + 14);
|
||||
const static int GIC_GPIO_IRQ = (32 + 116); // GPIO3
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (Control signals)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define ACT_OFF !ACT_ON
|
||||
#define ENB_OFF !ENB_ON
|
||||
#define TAD_OUT !TAD_IN
|
||||
#define IND_OUT !IND_IN
|
||||
#define DTD_OUT !DTD_IN
|
||||
#define ACT_OFF !ACT_ON
|
||||
#define ENB_OFF !ENB_ON
|
||||
#define TAD_OUT !TAD_IN
|
||||
#define IND_OUT !IND_IN
|
||||
#define DTD_OUT !DTD_IN
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (SCSI)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
#define IN GPIO_INPUT
|
||||
#define OUT GPIO_OUTPUT
|
||||
const static int ON = 1;
|
||||
const static int OFF = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constant declarations (bus control timing)
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
// SCSI Bus timings taken from:
|
||||
// https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-05.html
|
||||
const static int SCSI_DELAY_ARBITRATION_DELAY_NS = 2400;
|
||||
const static int SCSI_DELAY_ASSERTION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_BUS_CLEAR_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_FREE_DELAY_NS = 800;
|
||||
const static int SCSI_DELAY_BUS_SET_DELAY_NS = 1800;
|
||||
const static int SCSI_DELAY_BUS_SETTLE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_CABLE_SKEW_DELAY_NS = 10;
|
||||
const static int SCSI_DELAY_DATA_RELEASE_DELAY_NS = 400;
|
||||
const static int SCSI_DELAY_DESKEW_DELAY_NS = 45;
|
||||
const static int SCSI_DELAY_DISCONNECTION_DELAY_US = 200;
|
||||
const static int SCSI_DELAY_HOLD_TIME_NS = 45;
|
||||
const static int SCSI_DELAY_NEGATION_PERIOD_NS = 90;
|
||||
const static int SCSI_DELAY_POWER_ON_TO_SELECTION_TIME_S = 10; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_TO_SELECTION_TIME_US = 250*1000; // (recommended)
|
||||
const static int SCSI_DELAY_RESET_HOLD_TIME_US = 25;
|
||||
const static int SCSI_DELAY_SELECTION_ABORT_TIME_US = 200;
|
||||
const static int SCSI_DELAY_SELECTION_TIMEOUT_DELAY_NS = 250*1000; // (recommended)
|
||||
const static int SCSI_DELAY_FAST_ASSERTION_PERIOD_NS = 30;
|
||||
const static int SCSI_DELAY_FAST_CABLE_SKEW_DELAY_NS = 5;
|
||||
const static int SCSI_DELAY_FAST_DESKEW_DELAY_NS = 20;
|
||||
const static int SCSI_DELAY_FAST_HOLD_TIME_NS = 10;
|
||||
const static int SCSI_DELAY_FAST_NEGATION_PERIOD_NS = 30;
|
||||
|
||||
// The DaynaPort SCSI Link do a short delay in the middle of transfering
|
||||
// a packet. This is the number of uS that will be delayed between the
|
||||
// header and the actual data.
|
||||
const static int SCSI_DELAY_SEND_DATA_DAYNAPORT_US = 100;
|
||||
#define IN GPIO_INPUT
|
||||
#define OUT GPIO_OUTPUT
|
||||
const static int ON = 1;
|
||||
const static int OFF = 0;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Class definition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class GPIOBUS final : public BUS
|
||||
class GPIOBUS : public BUS
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
GPIOBUS()= default;
|
||||
~GPIOBUS() override = default;
|
||||
// Destructor
|
||||
bool Init(mode_e mode = mode_e::TARGET) override;
|
||||
// Initialization
|
||||
void Reset() override;
|
||||
// Reset
|
||||
void Cleanup() override;
|
||||
// Cleanup
|
||||
public:
|
||||
static GPIOBUS *create();
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Bus signal acquisition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
inline uint32_t Acquire() override
|
||||
{
|
||||
#if defined(__x86_64__) || defined(__X86__)
|
||||
// Only used for development/debugging purposes. Isn't really applicable
|
||||
// to any real-world RaSCSI application
|
||||
return 0;
|
||||
#else
|
||||
signals = *level;
|
||||
// Basic Functions
|
||||
GPIOBUS() = default;
|
||||
~GPIOBUS() override = default;
|
||||
// Destructor
|
||||
bool Init(mode_e mode = mode_e::TARGET) override;
|
||||
// Initialization
|
||||
void Reset() override;
|
||||
// Reset
|
||||
void Cleanup() override;
|
||||
// Cleanup
|
||||
|
||||
#if SIGNAL_CONTROL_MODE < 2
|
||||
// Invert if negative logic (internal processing is unified to positive logic)
|
||||
signals = ~signals;
|
||||
#endif // SIGNAL_CONTROL_MODE
|
||||
uint32_t Acquire() override = 0;
|
||||
|
||||
return signals;
|
||||
#endif // ifdef __x86_64__ || __X86__
|
||||
}
|
||||
void SetENB(bool ast);
|
||||
// Set ENB signal
|
||||
|
||||
void SetENB(bool ast);
|
||||
// Set ENB signal
|
||||
bool GetBSY() const override;
|
||||
// Get BSY signal
|
||||
void SetBSY(bool ast) override;
|
||||
// Set BSY signal
|
||||
|
||||
bool GetBSY() const override;
|
||||
// Get BSY signal
|
||||
void SetBSY(bool ast) override;
|
||||
// Set BSY signal
|
||||
bool GetSEL() const override;
|
||||
// Get SEL signal
|
||||
void SetSEL(bool ast) override;
|
||||
// Set SEL signal
|
||||
|
||||
bool GetSEL() const override;
|
||||
// Get SEL signal
|
||||
void SetSEL(bool ast) override;
|
||||
// Set SEL signal
|
||||
bool GetATN() const override;
|
||||
// Get ATN signal
|
||||
void SetATN(bool ast) override;
|
||||
// Set ATN signal
|
||||
|
||||
bool GetATN() const override;
|
||||
// Get ATN signal
|
||||
void SetATN(bool ast) override;
|
||||
// Set ATN signal
|
||||
bool GetACK() const override;
|
||||
// Get ACK signal
|
||||
void SetACK(bool ast) override;
|
||||
// Set ACK signal
|
||||
|
||||
bool GetACK() const override;
|
||||
// Get ACK signal
|
||||
void SetACK(bool ast) override;
|
||||
// Set ACK signal
|
||||
bool GetACT() const;
|
||||
// Get ACT signal
|
||||
void SetACT(bool ast);
|
||||
// Set ACT signal
|
||||
|
||||
bool GetACT() const;
|
||||
// Get ACT signal
|
||||
void SetACT(bool ast);
|
||||
// Set ACT signal
|
||||
bool GetRST() const override;
|
||||
// Get RST signal
|
||||
void SetRST(bool ast) override;
|
||||
// Set RST signal
|
||||
|
||||
bool GetRST() const override;
|
||||
// Get RST signal
|
||||
void SetRST(bool ast) override;
|
||||
// Set RST signal
|
||||
bool GetMSG() const override;
|
||||
// Get MSG signal
|
||||
void SetMSG(bool ast) override;
|
||||
// Set MSG signal
|
||||
|
||||
bool GetMSG() const override;
|
||||
// Get MSG signal
|
||||
void SetMSG(bool ast) override;
|
||||
// Set MSG signal
|
||||
bool GetCD() const override;
|
||||
// Get CD signal
|
||||
void SetCD(bool ast) override;
|
||||
// Set CD signal
|
||||
|
||||
bool GetCD() const override;
|
||||
// Get CD signal
|
||||
void SetCD(bool ast) override;
|
||||
// Set CD signal
|
||||
bool GetIO() override;
|
||||
// Get IO signal
|
||||
void SetIO(bool ast) override;
|
||||
// Set IO signal
|
||||
|
||||
bool GetIO() override;
|
||||
// Get IO signal
|
||||
void SetIO(bool ast) override;
|
||||
// Set IO signal
|
||||
bool GetREQ() const override;
|
||||
// Get REQ signal
|
||||
void SetREQ(bool ast) override;
|
||||
// Set REQ signal
|
||||
bool GetDP() const override;
|
||||
// Get Data parity signal
|
||||
int CommandHandShake(BYTE *buf) override;
|
||||
// Command receive handshake
|
||||
int ReceiveHandShake(BYTE *buf, int count) override;
|
||||
// Data receive handshake
|
||||
int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override;
|
||||
// Data transmission handshake
|
||||
|
||||
bool GetREQ() const override;
|
||||
// Get REQ signal
|
||||
void SetREQ(bool ast) override;
|
||||
// Set REQ signal
|
||||
static BUS::phase_t GetPhaseRaw(uint32_t raw_data);
|
||||
// Get the phase based on raw data
|
||||
|
||||
BYTE GetDAT() override;
|
||||
// Get DAT signal
|
||||
void SetDAT(BYTE dat) override;
|
||||
// Set DAT signal
|
||||
bool GetDP() const override;
|
||||
// Get Data parity signal
|
||||
int CommandHandShake(BYTE *buf) override;
|
||||
// Command receive handshake
|
||||
int ReceiveHandShake(BYTE *buf, int count) override;
|
||||
// Data receive handshake
|
||||
int SendHandShake(BYTE *buf, int count, int delay_after_bytes) override;
|
||||
// Data transmission handshake
|
||||
|
||||
static BUS::phase_t GetPhaseRaw(DWORD raw_data);
|
||||
// Get the phase based on raw data
|
||||
|
||||
static int GetCommandByteCount(BYTE opcode);
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
// SEL signal interrupt
|
||||
bool PollSelectEvent();
|
||||
// SEL signal event polling
|
||||
void ClearSelectEvent();
|
||||
// Clear SEL signal event
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
private:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable();
|
||||
// Create work data
|
||||
void SetControl(int pin, bool ast);
|
||||
// Set Control Signal
|
||||
void SetMode(int pin, int mode);
|
||||
// Set SCSI I/O mode
|
||||
bool GetSignal(int pin) const override;
|
||||
// Get SCSI input signal value
|
||||
void SetSignal(int pin, bool ast) override;
|
||||
// Set SCSI output signal value
|
||||
bool WaitSignal(int pin, int ast);
|
||||
// Wait for a signal to change
|
||||
// Interrupt control
|
||||
void DisableIRQ();
|
||||
// IRQ Disabled
|
||||
void EnableIRQ();
|
||||
// IRQ Enabled
|
||||
|
||||
// GPIO pin functionality settings
|
||||
void PinConfig(int pin, int mode);
|
||||
// GPIO pin direction setting
|
||||
void PullConfig(int pin, int mode);
|
||||
// GPIO pin pull up/down resistor setting
|
||||
void PinSetSignal(int pin, bool ast);
|
||||
// Set GPIO output signal
|
||||
void DrvConfig(DWORD drive);
|
||||
// Set GPIO drive strength
|
||||
|
||||
|
||||
mode_e actmode = mode_e::TARGET; // Operation mode
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
uint32_t baseaddr = 0; // Base address
|
||||
#endif
|
||||
|
||||
int rpitype = 0; // Type of Raspberry Pi
|
||||
|
||||
volatile uint32_t *gpio = nullptr; // GPIO register
|
||||
|
||||
volatile uint32_t *pads = nullptr; // PADS register
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *level = nullptr; // GPIO input level
|
||||
#endif
|
||||
|
||||
volatile uint32_t *irpctl = nullptr; // Interrupt control register
|
||||
|
||||
volatile uint32_t irptenb; // Interrupt enabled state
|
||||
|
||||
volatile uint32_t *qa7regs = nullptr; // QA7 register
|
||||
|
||||
volatile int tintcore; // Interupt control target CPU.
|
||||
|
||||
volatile uint32_t tintctl; // Interupt control
|
||||
|
||||
volatile uint32_t giccpmr; // GICC priority setting
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register
|
||||
#endif
|
||||
|
||||
volatile uint32_t *gicc = nullptr; // GIC CPU interface register
|
||||
|
||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
static int GetCommandByteCount(BYTE opcode);
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
struct gpioevent_request selevreq = {}; // SEL signal event request
|
||||
// SEL signal interrupt
|
||||
bool PollSelectEvent();
|
||||
// SEL signal event polling
|
||||
void ClearSelectEvent();
|
||||
// Clear SEL signal event
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
int epfd; // epoll file descriptor
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
protected:
|
||||
// SCSI I/O signal control
|
||||
virtual void MakeTable() = 0;
|
||||
// Create work data
|
||||
virtual void SetControl(int pin, bool ast) = 0;
|
||||
// Set Control Signal
|
||||
virtual void SetMode(int pin, int mode) = 0;
|
||||
// Set SCSI I/O mode
|
||||
bool GetSignal(int pin) const override = 0;
|
||||
// Set Control Signal
|
||||
void SetSignal(int pin, bool ast) override = 0;
|
||||
// Set SCSI I/O mode
|
||||
virtual bool WaitSignal(int pin, int ast) = 0;
|
||||
// Wait for a signal to change
|
||||
// Interrupt control
|
||||
virtual void DisableIRQ() = 0;
|
||||
// IRQ Disabled
|
||||
virtual void EnableIRQ() = 0;
|
||||
// IRQ Enabled
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
// GPIO pin functionality settings
|
||||
virtual void PinConfig(int pin, int mode) = 0;
|
||||
// GPIO pin direction setting
|
||||
virtual void PullConfig(int pin, int mode) = 0;
|
||||
// GPIO pin pull up/down resistor setting
|
||||
virtual void PinSetSignal(int pin, bool ast) = 0;
|
||||
// Set GPIO output signal
|
||||
virtual void DrvConfig(uint32_t drive) = 0;
|
||||
// Set GPIO drive strength
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
mode_e actmode = mode_e::TARGET; // Operation mode
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
uint32_t baseaddr = 0; // Base address
|
||||
#endif
|
||||
|
||||
static const array<int, 19> SignalTable; // signal table
|
||||
};
|
||||
static const array<int, 19> SignalTable; // signal table
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
struct gpioevent_request selevreq = {}; // SEL signal event request
|
||||
|
||||
int epfd; // epoll file descriptor
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
private:
|
||||
int rpitype = 0; // Type of Raspberry Pi
|
||||
|
||||
volatile uint32_t *gpio = nullptr; // GPIO register
|
||||
|
||||
volatile uint32_t *pads = nullptr; // PADS register
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *level = nullptr; // GPIO input level
|
||||
#endif
|
||||
|
||||
volatile uint32_t *irpctl = nullptr; // Interrupt control register
|
||||
|
||||
volatile uint32_t irptenb; // Interrupt enabled state
|
||||
|
||||
volatile uint32_t *qa7regs = nullptr; // QA7 register
|
||||
|
||||
volatile int tintcore; // Interupt control target CPU.
|
||||
|
||||
volatile uint32_t tintctl; // Interupt control
|
||||
|
||||
volatile uint32_t giccpmr; // GICC priority setting
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register
|
||||
#endif
|
||||
|
||||
volatile uint32_t *gicc = nullptr; // GIC CPU interface register
|
||||
|
||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
|
||||
array<uint32_t, 256> tblDatSet = {}; // Table setting table
|
||||
#endif
|
||||
};
|
||||
|
@ -16,41 +16,41 @@
|
||||
// RaSCSI Adapter Aibom version
|
||||
//
|
||||
|
||||
const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message
|
||||
const std::string CONNECT_DESC = "AIBOM PRODUCTS version"; // Startup message
|
||||
|
||||
// Select signal control mode
|
||||
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
|
||||
const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification
|
||||
|
||||
// Control signal output logic
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN OFF // DATA SIGNAL INPUT
|
||||
#define ACT_ON ON // ACTIVE SIGNAL ON
|
||||
#define ENB_ON ON // ENABLE SIGNAL ON
|
||||
#define IND_IN OFF // INITIATOR SIGNAL INPUT
|
||||
#define TAD_IN OFF // TARGET SIGNAL INPUT
|
||||
#define DTD_IN OFF // DATA SIGNAL INPUT
|
||||
|
||||
// Control signal pin assignment (-1 means no control)
|
||||
const static int PIN_ACT = 4; // ACTIVE
|
||||
const static int PIN_ENB = 17; // ENABLE
|
||||
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = 18; // DATA DIRECTION
|
||||
const static int PIN_ACT = 4; // ACTIVE
|
||||
const static int PIN_ENB = 17; // ENABLE
|
||||
const static int PIN_IND = 27; // INITIATOR CTRL DIRECTION
|
||||
const static int PIN_TAD = -1; // TARGET CTRL DIRECTION
|
||||
const static int PIN_DTD = 18; // DATA DIRECTION
|
||||
|
||||
// SCSI signal pin assignment
|
||||
const static int PIN_DT0 = 6; // Data 0
|
||||
const static int PIN_DT1 = 12; // Data 1
|
||||
const static int PIN_DT2 = 13; // Data 2
|
||||
const static int PIN_DT3 = 16; // Data 3
|
||||
const static int PIN_DT4 = 19; // Data 4
|
||||
const static int PIN_DT5 = 20; // Data 5
|
||||
const static int PIN_DT6 = 26; // Data 6
|
||||
const static int PIN_DT7 = 21; // Data 7
|
||||
const static int PIN_DP = 5; // Data parity
|
||||
const static int PIN_ATN = 22; // ATN
|
||||
const static int PIN_RST = 25; // RST
|
||||
const static int PIN_ACK = 10; // ACK
|
||||
const static int PIN_REQ = 7; // REQ
|
||||
const static int PIN_MSG = 9; // MSG
|
||||
const static int PIN_CD = 11; // CD
|
||||
const static int PIN_IO = 23; // IO
|
||||
const static int PIN_BSY = 24; // BSY
|
||||
const static int PIN_SEL = 8; // SEL
|
||||
const static int PIN_DT0 = 6; // Data 0
|
||||
const static int PIN_DT1 = 12; // Data 1
|
||||
const static int PIN_DT2 = 13; // Data 2
|
||||
const static int PIN_DT3 = 16; // Data 3
|
||||
const static int PIN_DT4 = 19; // Data 4
|
||||
const static int PIN_DT5 = 20; // Data 5
|
||||
const static int PIN_DT6 = 26; // Data 6
|
||||
const static int PIN_DT7 = 21; // Data 7
|
||||
const static int PIN_DP = 5; // Data parity
|
||||
const static int PIN_ATN = 22; // ATN
|
||||
const static int PIN_RST = 25; // RST
|
||||
const static int PIN_ACK = 10; // ACK
|
||||
const static int PIN_REQ = 7; // REQ
|
||||
const static int PIN_MSG = 9; // MSG
|
||||
const static int PIN_CD = 11; // CD
|
||||
const static int PIN_IO = 23; // IO
|
||||
const static int PIN_BSY = 24; // BSY
|
||||
const static int PIN_SEL = 8; // SEL
|
||||
|
120
src/raspberrypi/hal/gpiobus_allwinner.cpp
Normal file
120
src/raspberrypi/hal/gpiobus_allwinner.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
//
|
||||
// [ GPIO-SCSI bus ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "hal/gpiobus_allwinner.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "log.h"
|
||||
|
||||
extern int wiringPiMode;
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
bool GPIOBUS_Allwinner::Init(mode_e mode)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::Cleanup()
|
||||
{
|
||||
LOGTRACE("%s", __PRETTY_FUNCTION__)
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::Reset(){LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)}
|
||||
|
||||
BYTE GPIOBUS_Allwinner::GetDAT()
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetDAT(BYTE dat)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::MakeTable(void)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetControl(int pin, bool ast)
|
||||
{
|
||||
GPIOBUS_Allwinner::SetSignal(pin, ast);
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetMode(int pin, int mode)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
bool GPIOBUS_Allwinner::GetSignal(int pin) const
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
return false;
|
||||
// return (digitalRead(pin) != 0);
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::SetSignal(int pin, bool ast)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
bool GPIOBUS_Allwinner::WaitSignal(int pin, int ast)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
return false;
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::DisableIRQ()
|
||||
{
|
||||
LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::EnableIRQ()
|
||||
{
|
||||
LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::PinConfig(int pin, int mode)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::PullConfig(int pin, int mode)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::PinSetSignal(int pin, bool ast)
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
void GPIOBUS_Allwinner::DrvConfig(DWORD drive)
|
||||
{
|
||||
(void)drive;
|
||||
LOGERROR("%s not implemented!!", __PRETTY_FUNCTION__)
|
||||
}
|
||||
|
||||
uint32_t GPIOBUS_Allwinner::Acquire()
|
||||
{
|
||||
LOGWARN("%s NOT IMPLEMENTED", __PRETTY_FUNCTION__)
|
||||
// Only used for development/debugging purposes. Isn't really applicable
|
||||
// to any real-world RaSCSI application
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
128
src/raspberrypi/hal/gpiobus_allwinner.h
Normal file
128
src/raspberrypi/hal/gpiobus_allwinner.h
Normal file
@ -0,0 +1,128 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// SCSI Target Emulator RaSCSI Reloaded
|
||||
// for Raspberry Pi
|
||||
//
|
||||
// Powered by XM6 TypeG Technology.
|
||||
// Copyright (C) 2016-2020 GIMONS
|
||||
// [ GPIO-SCSI bus ]
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include "hal/gpiobus.h"
|
||||
#include "log.h"
|
||||
#include "scsi.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Class definition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
class GPIOBUS_Allwinner : public GPIOBUS
|
||||
{
|
||||
public:
|
||||
// Basic Functions
|
||||
GPIOBUS_Allwinner() = default;
|
||||
~GPIOBUS_Allwinner() override = default;
|
||||
// Destructor
|
||||
bool Init(mode_e mode = mode_e::TARGET) override;
|
||||
// Initialization
|
||||
void Reset() override;
|
||||
// Reset
|
||||
void Cleanup() override;
|
||||
// Cleanup
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Bus signal acquisition
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
uint32_t Acquire() override;
|
||||
|
||||
BYTE GetDAT() override;
|
||||
// Get DAT signal
|
||||
void SetDAT(BYTE dat) override;
|
||||
// Set DAT signal
|
||||
protected:
|
||||
// SCSI I/O signal control
|
||||
void MakeTable() override;
|
||||
// Create work data
|
||||
void SetControl(int pin, bool ast) override;
|
||||
// Set Control Signal
|
||||
void SetMode(int pin, int mode) override;
|
||||
// Set SCSI I/O mode
|
||||
bool GetSignal(int pin) const override;
|
||||
// Get SCSI input signal value
|
||||
void SetSignal(int pin, bool ast) override;
|
||||
// Set SCSI output signal value
|
||||
bool WaitSignal(int pin, int ast) override;
|
||||
// Wait for a signal to change
|
||||
// Interrupt control
|
||||
void DisableIRQ() override;
|
||||
// IRQ Disabled
|
||||
void EnableIRQ() override;
|
||||
// IRQ Enabled
|
||||
|
||||
// GPIO pin functionality settings
|
||||
void PinConfig(int pin, int mode) override;
|
||||
// GPIO pin direction setting
|
||||
void PullConfig(int pin, int mode) override;
|
||||
// GPIO pin pull up/down resistor setting
|
||||
void PinSetSignal(int pin, bool ast) override;
|
||||
// Set GPIO output signal
|
||||
void DrvConfig(DWORD drive) override;
|
||||
// Set GPIO drive strength
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
uint32_t baseaddr = 0; // Base address
|
||||
#endif
|
||||
|
||||
volatile uint32_t *gpio = nullptr; // GPIO register
|
||||
|
||||
volatile uint32_t *pads = nullptr; // PADS register
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *level = nullptr; // GPIO input level
|
||||
#endif
|
||||
|
||||
volatile uint32_t *irpctl = nullptr; // Interrupt control register
|
||||
|
||||
volatile uint32_t irptenb; // Interrupt enabled state
|
||||
|
||||
volatile uint32_t *qa7regs = nullptr; // QA7 register
|
||||
|
||||
volatile int tintcore; // Interupt control target CPU.
|
||||
|
||||
volatile uint32_t tintctl; // Interupt control
|
||||
|
||||
volatile uint32_t giccpmr; // GICC priority setting
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__X86__)
|
||||
volatile uint32_t *gicd = nullptr; // GIC Interrupt distributor register
|
||||
#endif
|
||||
|
||||
volatile uint32_t *gicc = nullptr; // GIC CPU interface register
|
||||
|
||||
array<uint32_t, 4> gpfsel; // GPFSEL0-4 backup values
|
||||
|
||||
uint32_t signals = 0; // All bus signals
|
||||
|
||||
#ifdef USE_SEL_EVENT_ENABLE
|
||||
struct gpioevent_request selevreq = {}; // SEL signal event request
|
||||
|
||||
int epfd; // epoll file descriptor
|
||||
#endif // USE_SEL_EVENT_ENABLE
|
||||
|
||||
#if SIGNAL_CONTROL_MODE == 0
|
||||
array<array<uint32_t, 256>, 3> tblDatMsk; // Data mask table
|
||||
|
||||
array<array<uint32_t, 256>, 3> tblDatSet; // Data setting table
|
||||
#else
|
||||
array<uint32_t, 256> tblDatMsk = {}; // Data mask table
|
||||
|