From e64c2f7254b6dc0f051484ef24693e9f76d0d47f Mon Sep 17 00:00:00 2001 From: akuker <34318535+akuker@users.noreply.github.com> Date: Sat, 10 Sep 2022 16:40:24 -0500 Subject: [PATCH] Breakup GPIOBUS (#843) * moved gpiobus * moved gpiobus and systimer into hardware abstraction layer * split up gpiobus by connection type * merge develop changes * revert compiler setting change * registers working * updates * updates * Revert "updates" This reverts commit 0134b810612581893bf6e831ddcd9a2b430a41ed. * Revert "updates" This reverts commit 4bf0416ab4602614c1a8fbb2fab3d9658f6cddff. * Revert "registers working" This reverts commit f5ee073eafa7acc83f2aa3badf23552da30d68ed. * Address comment in #843. Restore -Wextra Co-authored-by: Tony Kuker --- src/raspberrypi/Makefile | 11 +- .../controllers/scsi_controller.cpp | 3 +- src/raspberrypi/{ => hal}/gpiobus.cpp | 121 +--------- src/raspberrypi/{ => hal}/gpiobus.h | 223 +----------------- src/raspberrypi/hal/gpiobus_aibom.h | 55 +++++ src/raspberrypi/hal/gpiobus_fullspec.h | 53 +++++ src/raspberrypi/hal/gpiobus_gamernium.h | 56 +++++ src/raspberrypi/hal/gpiobus_standard.h | 54 +++++ src/raspberrypi/hal/systimer.cpp | 140 +++++++++++ src/raspberrypi/hal/systimer.h | 47 ++++ src/raspberrypi/monitor/data_sample.h | 2 +- src/raspberrypi/monitor/sm_vcd_report.cpp | 2 +- src/raspberrypi/rascsi.cpp | 3 +- src/raspberrypi/rasdump.cpp | 3 +- src/raspberrypi/scsimon.cpp | 2 +- 15 files changed, 434 insertions(+), 341 deletions(-) rename src/raspberrypi/{ => hal}/gpiobus.cpp (91%) rename src/raspberrypi/{ => hal}/gpiobus.h (67%) create mode 100644 src/raspberrypi/hal/gpiobus_aibom.h create mode 100644 src/raspberrypi/hal/gpiobus_fullspec.h create mode 100644 src/raspberrypi/hal/gpiobus_gamernium.h create mode 100644 src/raspberrypi/hal/gpiobus_standard.h create mode 100644 src/raspberrypi/hal/systimer.cpp create mode 100644 src/raspberrypi/hal/systimer.h diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 5f125b75..12fe637e 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -87,7 +87,6 @@ SRC_PROTOBUF = \ SRC_RASCSI_CORE = \ scsi.cpp \ - gpiobus.cpp \ filepath.cpp \ fileio.cpp \ rascsi_version.cpp \ @@ -98,6 +97,7 @@ SRC_RASCSI_CORE = \ localizer.cpp SRC_RASCSI_CORE += $(shell find ./controllers -name '*.cpp') SRC_RASCSI_CORE += $(shell find ./devices -name '*.cpp') +SRC_RASCSI_CORE += $(shell find ./hal -name '*.cpp') SRC_RASCSI_CORE += $(SRC_PROTOBUF) SRC_RASCSI = rascsi.cpp @@ -105,9 +105,9 @@ SRC_RASCSI = rascsi.cpp SRC_SCSIMON = \ scsimon.cpp \ scsi.cpp \ - gpiobus.cpp \ rascsi_version.cpp SRC_SCSIMON += $(shell find ./monitor -name '*.cpp') +SRC_SCSIMON += $(shell find ./hal -name '*.cpp') SRC_RASCTL = \ rasctl.cpp\ @@ -122,17 +122,16 @@ SRC_RASCTL += $(SRC_PROTOBUF) SRC_RASDUMP = \ rasdump.cpp \ scsi.cpp \ - gpiobus.cpp \ filepath.cpp \ fileio.cpp \ rascsi_version.cpp - +SRC_RASDUMP += $(shell find ./hal -name '*.cpp') SRC_RASCSI_TEST = $(shell find ./test -name '*.cpp') -vpath %.h ./ ./controllers ./devices ./monitor -vpath %.cpp ./ ./controllers ./devices ./monitor ./test +vpath %.h ./ ./controllers ./devices ./monitor ./hal +vpath %.cpp ./ ./controllers ./devices ./monitor ./test ./hal vpath %.o ./$(OBJDIR) vpath ./$(BINDIR) diff --git a/src/raspberrypi/controllers/scsi_controller.cpp b/src/raspberrypi/controllers/scsi_controller.cpp index fd23783a..7864f0c3 100644 --- a/src/raspberrypi/controllers/scsi_controller.cpp +++ b/src/raspberrypi/controllers/scsi_controller.cpp @@ -15,7 +15,8 @@ //--------------------------------------------------------------------------- #include "log.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" +#include "hal/systimer.h" #include "rascsi_exceptions.h" #include "devices/scsi_host_bridge.h" #include "devices/scsi_daynaport.h" diff --git a/src/raspberrypi/gpiobus.cpp b/src/raspberrypi/hal/gpiobus.cpp similarity index 91% rename from src/raspberrypi/gpiobus.cpp rename to src/raspberrypi/hal/gpiobus.cpp index c7470f56..c558cfb8 100644 --- a/src/raspberrypi/gpiobus.cpp +++ b/src/raspberrypi/hal/gpiobus.cpp @@ -13,7 +13,8 @@ #include #include "os.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" +#include "hal/systimer.h" #include "config.h" #include "log.h" @@ -1452,121 +1453,3 @@ int GPIOBUS::GetCommandByteCount(BYTE opcode) { } } -//--------------------------------------------------------------------------- -// -// System timer address -// -//--------------------------------------------------------------------------- -volatile DWORD* SysTimer::systaddr; - -//--------------------------------------------------------------------------- -// -// ARM timer address -// -//--------------------------------------------------------------------------- -volatile DWORD* SysTimer::armtaddr; - -//--------------------------------------------------------------------------- -// -// Core frequency -// -//--------------------------------------------------------------------------- -volatile DWORD SysTimer::corefreq; - -//--------------------------------------------------------------------------- -// -// Initialize the system timer -// -//--------------------------------------------------------------------------- -void SysTimer::Init(DWORD *syst, DWORD *armt) -{ - // 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 - DWORD maxclock[32] = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 }; - - // 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); -} - -//--------------------------------------------------------------------------- -// -// Get system timer low byte -// -//--------------------------------------------------------------------------- -DWORD SysTimer::GetTimerLow() { - return systaddr[SYST_CLO]; -} - -//--------------------------------------------------------------------------- -// -// Get system timer high byte -// -//--------------------------------------------------------------------------- -DWORD SysTimer::GetTimerHigh() { - return systaddr[SYST_CHI]; -} - -//--------------------------------------------------------------------------- -// -// Sleep in nanoseconds -// -//--------------------------------------------------------------------------- -void SysTimer::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::SleepUsec(DWORD usec) -{ - // If time is 0, don't do anything - if (usec == 0) { - return; - } - - DWORD now = GetTimerLow(); - while ((GetTimerLow() - now) < usec); -} diff --git a/src/raspberrypi/gpiobus.h b/src/raspberrypi/hal/gpiobus.h similarity index 67% rename from src/raspberrypi/gpiobus.h rename to src/raspberrypi/hal/gpiobus.h index 7d049c13..94562bf2 100644 --- a/src/raspberrypi/gpiobus.h +++ b/src/raspberrypi/hal/gpiobus.h @@ -9,8 +9,7 @@ // //--------------------------------------------------------------------------- -#if !defined(gpiobus_h) -#define gpiobus_h +#pragma once #include "config.h" #include "scsi.h" @@ -25,6 +24,18 @@ //#define CONNECT_TYPE_AIBOM // AIBOM version (positive logic, unique pin assignment) //#define CONNECT_TYPE_GAMERNIUM // GAMERnium.com version (standard logic, unique pin assignment) +#if defined CONNECT_TYPE_STANDARD +#include "hal/gpiobus_standard.h" +#elif defined CONNECT_TYPE_FULLSPEC +#include "hal/gpiobus_fullspec.h" +#elif defined CONNECT_TYPE_AIBOM +#include "hal/gpiobus_aibom.h" +#elif defined CONNECT_TYPE_GAMERNIUM +#include "hal/gpiobus_gamernium.h" +#else +#error Invalid connection type or none specified +#endif + //--------------------------------------------------------------------------- // // Signal control logic and pin assignment customization @@ -99,185 +110,6 @@ // //--------------------------------------------------------------------------- -#ifdef CONNECT_TYPE_STANDARD -// -// RaSCSI standard (SCSI logic, standard pin assignment) -// -#define CONNECT_DESC "STANDARD" // Startup message - -// Select signal control mode -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 - -// Control signal output logic -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // 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 -#endif - -#ifdef CONNECT_TYPE_FULLSPEC -// -// RaSCSI standard (SCSI logic, standard pin assignment) -// -#define CONNECT_DESC "FULLSPEC" // Startup message - -// Select signal control mode -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 - -// Control signal output logic -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // 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 -#endif - -#ifdef CONNECT_TYPE_AIBOM -// -// RaSCSI Adapter Aibom version -// - -#define CONNECT_DESC "AIBOM PRODUCTS version" // Startup message - -// Select signal control mode -const static int SIGNAL_CONTROL_MODE = 2; // SCSI positive logic specification - -// Control signal output logic -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN FALSE // 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 - -// 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 -#endif - -// TODO Is this type stil relevant? -#ifdef CONNECT_TYPE_GAMERNIUM -// -// RaSCSI Adapter GAMERnium.com version -// - -#define CONNECT_DESC "GAMERnium.com version"// Startup message - -// Select signal control mode -const static int SIGNAL_CONTROL_MODE = 0; // SCSI logical specification - -// Control signal output logic -#define ACT_ON TRUE // ACTIVE SIGNAL ON -#define ENB_ON TRUE // ENABLE SIGNAL ON -#define IND_IN FALSE // INITIATOR SIGNAL INPUT -#define TAD_IN FALSE // TARGET SIGNAL INPUT -#define DTD_IN TRUE // 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 - -// 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 -#endif - #define ALL_SCSI_PINS \ ((1< + +#include "os.h" +#include "hal/gpiobus.h" + +#include "config.h" +#include "log.h" + +//--------------------------------------------------------------------------- +// +// System timer address +// +//--------------------------------------------------------------------------- +volatile DWORD* SysTimer::systaddr; + +//--------------------------------------------------------------------------- +// +// ARM timer address +// +//--------------------------------------------------------------------------- +volatile DWORD* SysTimer::armtaddr; + +//--------------------------------------------------------------------------- +// +// Core frequency +// +//--------------------------------------------------------------------------- +volatile DWORD SysTimer::corefreq; + +//--------------------------------------------------------------------------- +// +// Initialize the system timer +// +//--------------------------------------------------------------------------- +void SysTimer::Init(DWORD *syst, DWORD *armt) +{ + // 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 + DWORD maxclock[32] = { 32, 0, 0x00030004, 8, 0, 4, 0, 0 }; + + // 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); +} + +//--------------------------------------------------------------------------- +// +// Get system timer low byte +// +//--------------------------------------------------------------------------- +DWORD SysTimer::GetTimerLow() { + return systaddr[SYST_CLO]; +} + +//--------------------------------------------------------------------------- +// +// Get system timer high byte +// +//--------------------------------------------------------------------------- +DWORD SysTimer::GetTimerHigh() { + return systaddr[SYST_CHI]; +} + +//--------------------------------------------------------------------------- +// +// Sleep in nanoseconds +// +//--------------------------------------------------------------------------- +void SysTimer::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::SleepUsec(DWORD usec) +{ + // If time is 0, don't do anything + if (usec == 0) { + return; + } + + DWORD now = GetTimerLow(); + while ((GetTimerLow() - now) < usec); +} diff --git a/src/raspberrypi/hal/systimer.h b/src/raspberrypi/hal/systimer.h new file mode 100644 index 00000000..8f4b31d9 --- /dev/null +++ b/src/raspberrypi/hal/systimer.h @@ -0,0 +1,47 @@ +//--------------------------------------------------------------------------- +// +// 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 + +#include "config.h" +#include "scsi.h" + +//=========================================================================== +// +// System timer +// +//=========================================================================== +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 + +private: + static volatile uint32_t *systaddr; + // System timer address + static volatile uint32_t *armtaddr; + // ARM timer address + static volatile uint32_t corefreq; + // Core frequency +}; diff --git a/src/raspberrypi/monitor/data_sample.h b/src/raspberrypi/monitor/data_sample.h index 91d598e6..72efc2bd 100644 --- a/src/raspberrypi/monitor/data_sample.h +++ b/src/raspberrypi/monitor/data_sample.h @@ -12,7 +12,7 @@ #pragma once #include "scsi.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" using data_capture_t = struct data_capture { diff --git a/src/raspberrypi/monitor/sm_vcd_report.cpp b/src/raspberrypi/monitor/sm_vcd_report.cpp index 0b1f76db..747bbeec 100644 --- a/src/raspberrypi/monitor/sm_vcd_report.cpp +++ b/src/raspberrypi/monitor/sm_vcd_report.cpp @@ -17,7 +17,7 @@ #include #include "data_sample.h" #include "sm_reports.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" using namespace std; diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 7105220c..2bccfb25 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -17,7 +17,8 @@ #include "devices/device.h" #include "devices/disk.h" #include "devices/file_support.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" +#include "hal/systimer.h" #include "rascsi_exceptions.h" #include "protobuf_util.h" #include "rascsi_version.h" diff --git a/src/raspberrypi/rasdump.cpp b/src/raspberrypi/rasdump.cpp index b77c6604..e31fe570 100644 --- a/src/raspberrypi/rasdump.cpp +++ b/src/raspberrypi/rasdump.cpp @@ -13,7 +13,8 @@ #include "os.h" #include "fileio.h" #include "filepath.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" +#include "hal/systimer.h" #include "rascsi_version.h" //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/scsimon.cpp b/src/raspberrypi/scsimon.cpp index 3cdcbb9e..4eb1fc2a 100644 --- a/src/raspberrypi/scsimon.cpp +++ b/src/raspberrypi/scsimon.cpp @@ -10,7 +10,7 @@ #include "os.h" #include "log.h" -#include "gpiobus.h" +#include "hal/gpiobus.h" #include "rascsi_version.h" #include "spdlog/spdlog.h" #include