#7 Re-merge scsimon functionality with latest master. The old scsimon branch was waaaaay too out of date

This commit is contained in:
akuker 2020-10-18 17:11:12 -05:00
parent 236473f872
commit 3a61b500c2
10 changed files with 201 additions and 76 deletions

View File

@ -4,6 +4,7 @@
*.cbp
*.layout
*.log
*.vcd
rascsi
scsimon
rasctl

View File

@ -38,8 +38,8 @@ CXXFLAGS += -std=c++14 -iquote . -MD -MP
## STANDARD or FULLSPEC. The default is STANDARD
## * THIS IS TYPICALLY THE ONLY COMPILE OPTION YOU
## * NEED TO SPECIFY
# If its not specified, build for STANDARD configuration
CONNECT_TYPE ?= STANDARD
# If its not specified, build for FULLSPEC configuration
CONNECT_TYPE ?= FULLSPEC
ifdef CONNECT_TYPE
CFLAGS += -DCONNECT_TYPE_$(CONNECT_TYPE)
@ -67,8 +67,7 @@ BINDIR := ./bin/$(shell echo $(CONNECT_TYPE) | tr '[:upper:]' '[:lower:]')
#BIN_ALL = $(RASCSI) $(RASCTL) $(RASDUMP) $(SASIDUMP) $(SCSIMON)
# Temporarily remove the RASDUMP and RASDUMP tools, since they're not needed
# for my specific use case. If you need them - add them back in!
BIN_ALL = $(BINDIR)/$(RASCSI) $(BINDIR)/$(RASCTL)
BIN_ALL = $(BINDIR)/$(RASCSI) $(BINDIR)/$(RASCTL) $(BINDIR)/$(SCSIMON)
SRC_RASCSI = \
rascsi.cpp \
@ -83,6 +82,16 @@ SRC_RASCSI = \
SRC_RASCSI += $(shell find ./controllers -name '*.cpp')
SRC_RASCSI += $(shell find ./devices -name '*.cpp')
SRC_SCSIMON = \
scsimon.cpp \
scsi.cpp \
gpiobus.cpp \
filepath.cpp \
fileio.cpp
SRC_SCSIMON += $(shell find ./controllers -name '*.cpp')
SRC_SCSIMON += $(shell find ./devices -name '*.cpp')
SRC_RASCTL = \
rasctl.cpp
# rasctl_command.cpp
@ -113,12 +122,12 @@ OBJ_RASDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_RASDUMP:%.cpp=%.o)))
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
#OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSIMON)
OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP)
OBJ_ALL := $(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_RASDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSIMON)
# The following will include all of the auto-generated dependency files (*.d)
# if they exist. This will trigger a rebuild of a source file if a header changes
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI) $(OBJ_RASCTL))
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_RASCSI) $(OBJ_RASCTL) $(OBJ_SCSIMON))
-include $(ALL_DEPS)
$(OBJDIR) $(BINDIR):
@ -137,21 +146,21 @@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR)
all: $(BIN_ALL) docs
ALL: all
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt
docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt
$(BINDIR)/$(RASCSI): $(OBJ_RASCSI) | $(BINDIR)
$(CXX) -o $@ $(OBJ_RASCSI) -lpthread
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread
$(BINDIR)/$(RASCTL): $(OBJ_RASCTL) $(BINDIR)
$(CXX) -o $@ $(OBJ_RASCTL)
$(BINDIR)/$(RASCTL): $(OBJ_RASCTL) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL)
$(RASDUMP): $(OBJ_RASDUMP) $(BINDIR)
$(CXX) -o $@ $(OBJ_RASDUMP)
$(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP)
$(SASIDUMP): $(OBJ_SASIDUMP) $(BINDIR)
$(CXX) -o $@ $(OBJ_SASIDUMP)
$(BINDIR)/$(SASIDUMP): $(OBJ_SASIDUMP) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SASIDUMP)
$(SCSIMON): $(OBJ_SCSIMON) $(BINDIR)
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) | $(BINDIR)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ_SCSIMON) -lpthread
## clean : Remove all of the object files, intermediate
@ -180,7 +189,7 @@ run:
## * sudo systemctl enable rascsi
## * sudo systemctl start rascsi
.PHONY: install
install: $(MAN_PAGE_DIR)/rascsi.1 $(MAN_PAGE_DIR)/rasctl.1 $(USR_LOCAL_BIN)/$(RASCTL) $(USR_LOCAL_BIN)/$(RASCSI) $(SYSTEMD_CONF) $(RSYSLOG_CONF) $(RSYSLOG_LOG)
install: $(MAN_PAGE_DIR)/rascsi.1 $(MAN_PAGE_DIR)/rasctl.1 $(MAN_PAGE_DIR)/scsimon.1 $(USR_LOCAL_BIN)/$(RASCTL) $(USR_LOCAL_BIN)/$(RASCSI) $(USR_LOCAL_BIN)/$(SCSIMON) $(SYSTEMD_CONF) $(RSYSLOG_CONF) $(RSYSLOG_LOG)
@echo "-- Done installing!"
$(USR_LOCAL_BIN)% : $(BINDIR)/%

View File

@ -296,7 +296,7 @@ BUS::phase_t FASTCALL SASIDEV::Process()
}
// Get bus information
ctrl.bus->Aquire();
((GPIOBUS*)ctrl.bus)->Aquire();
// For the monitor tool, we shouldn't need to reset. We're just logging information
// Reset
@ -927,7 +927,7 @@ void FASTCALL SASIDEV::Error()
ASSERT(this);
// Get bus information
ctrl.bus->Aquire();
((GPIOBUS*)ctrl.bus)->Aquire();
// Reset check
if (ctrl.bus->GetRST()) {

View File

@ -76,7 +76,7 @@ BUS::phase_t FASTCALL SCSIDEV::Process()
}
// Get bus information
ctrl.bus->Aquire();
((GPIOBUS*)ctrl.bus)->Aquire();
// Reset
if (ctrl.bus->GetRST()) {
@ -488,7 +488,7 @@ void FASTCALL SCSIDEV::Error()
ASSERT(this);
// Get bus information
ctrl.bus->Aquire();
((GPIOBUS*)ctrl.bus)->Aquire();
// Reset check
if (ctrl.bus->GetRST()) {

View File

@ -15,6 +15,7 @@
#include "os.h"
#include "xm6.h"
#include "gpiobus.h"
#include "log.h"
#ifndef BAREMETAL
#ifdef __linux__
@ -65,7 +66,7 @@ DWORD bcm_host_get_peripheral_address(void)
char buf[1024];
size_t len = sizeof(buf);
DWORD address;
if (sysctlbyname("hw.model", buf, &len, NULL, 0) ||
strstr(buf, "ARM1176JZ-S") != buf) {
// Failed to get CPU model || Not BCM2835
@ -88,7 +89,7 @@ extern uint32_t RPi_IO_Base_Addr;
// Core frequency
extern uint32_t RPi_Core_Freq;
#ifdef USE_SEL_EVENT_ENABLE
#ifdef USE_SEL_EVENT_ENABLE
//---------------------------------------------------------------------------
//
// Interrupt control function
@ -173,7 +174,7 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode)
// Open /dev/mem
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
printf("Error: Unable to open /dev/mem. Are you running as root?\n");
LOGERROR("Error: Unable to open /dev/mem. Are you running as root?");
return FALSE;
}
@ -295,6 +296,7 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode)
// GPIO chip open
fd = open("/dev/gpiochip0", 0);
if (fd == -1) {
LOGERROR("Unable to open /dev/gpiochip0. Is RaSCSI already running?")
return FALSE;
}
@ -310,6 +312,7 @@ BOOL FASTCALL GPIOBUS::Init(mode_e mode)
//Get event request
if (ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &selevreq) == -1) {
LOGERROR("Unable to register event request. Is RaSCSI already running?")
close(fd);
return FALSE;
}
@ -522,27 +525,6 @@ void FASTCALL GPIOBUS::Reset()
#endif // ifdef __x86_64__ || __X86__
}
//---------------------------------------------------------------------------
//
// Bus signal acquisition
//
//---------------------------------------------------------------------------
DWORD FASTCALL GPIOBUS::Aquire()
{
#if defined(__x86_64__) || defined(__X86__)
return 0;
#else
signals = *level;
#if SIGNAL_CONTROL_MODE < 2
// Invert if negative logic (internal processing is unified to positive logic)
signals = ~signals;
#endif // SIGNAL_CONTROL_MODE
return signals;
#endif // ifdef __x86_64__ || __X86__
}
//---------------------------------------------------------------------------
//
// ENB signal setting
@ -1173,7 +1155,7 @@ int FASTCALL GPIOBUS::SendHandShake(BYTE *buf, int count)
}
// Already waiting for REQ assertion
// Assert the ACK signal
SetSignal(PIN_ACK, ON);
@ -1417,7 +1399,7 @@ void FASTCALL GPIOBUS::SetMode(int pin, int mode)
gpio[index] = data;
gpfsel[index] = data;
}
//---------------------------------------------------------------------------
//
// Get input signal value
@ -1427,7 +1409,7 @@ BOOL FASTCALL GPIOBUS::GetSignal(int pin)
{
return (signals >> pin) & 1;
}
//---------------------------------------------------------------------------
//
// Set output signal value
@ -1645,6 +1627,39 @@ void FASTCALL GPIOBUS::DrvConfig(DWORD drive)
pads[PAD_0_27] = (0xFFFFFFF8 & data) | drive | 0x5a000000;
}
//---------------------------------------------------------------------------
//
// Generic Phase Acquisition (Doesn't read GPIO)
//
//---------------------------------------------------------------------------
BUS::phase_t FASTCALL GPIOBUS::GetPhaseRaw(DWORD raw_data)
{
DWORD mci;
// Selection Phase
if (GetPinRaw(raw_data, PIN_SEL))
{
if(GetPinRaw(raw_data, PIN_IO)){
return BUS::reselection;
}else{
return BUS::selection;
}
}
// Bus busy phase
if (!GetPinRaw(raw_data, PIN_BSY)) {
return BUS::busfree;
}
// Get target phase from bus signal line
mci = GetPinRaw(raw_data, PIN_MSG) ? 0x04 : 0x00;
mci |= GetPinRaw(raw_data, PIN_CD) ? 0x02 : 0x00;
mci |= GetPinRaw(raw_data, PIN_IO) ? 0x01 : 0x00;
return GetPhase(mci);
}
//---------------------------------------------------------------------------
//
// System timer address

View File

@ -276,6 +276,26 @@
#define PIN_SEL 23 // SEL
#endif
#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)
@ -434,8 +454,28 @@ public:
void FASTCALL Cleanup();
// Cleanup
DWORD FASTCALL Aquire();
// Signal acquisition
//---------------------------------------------------------------------------
//
// Bus signal acquisition
//
//---------------------------------------------------------------------------
inline DWORD Aquire()
{
#if defined(__x86_64__) || defined(__X86__)
// Only used for development/debugging purposes. Isn't really applicable
// to any real-world RaSCSI application
return 0;
#else
signals = *level;
#if SIGNAL_CONTROL_MODE < 2
// Invert if negative logic (internal processing is unified to positive logic)
signals = ~signals;
#endif // SIGNAL_CONTROL_MODE
return signals;
#endif // ifdef __x86_64__ || __X86__
}
void FASTCALL SetENB(BOOL ast);
// Set ENB signal
@ -498,6 +538,9 @@ public:
int FASTCALL SendHandShake(BYTE *buf, int count);
// Data transmission handshake
static BUS::phase_t FASTCALL GetPhaseRaw(DWORD raw_data);
// Get the phase based on raw data
#ifdef USE_SEL_EVENT_ENABLE
// SEL signal interrupt
int FASTCALL PollSelectEvent();

View File

@ -5,27 +5,34 @@
//
// Powered by XM6 TypeG Technology.
// Copyright (C) 2016-2020 GIMONS
// [ ログ ]
// Copyright (C) 2020 akuker
// [ Logging utilities ]
//
//---------------------------------------------------------------------------
#if !defined(log_h)
#define log_h
//===========================================================================
//
// ログ
//
//===========================================================================
class Log
{
public:
enum loglevel {
Detail, // 詳細レベル
Normal, // 通常レベル
Warning, // 警告レベル
Debug // デバッグレベル
};
};
#include "spdlog/spdlog.h"
#include "spdlog/sinks/sink.h"
#define SPDLOGWRAPPER(loglevel, ...)\
do{ char buf[256]; \
snprintf(buf, sizeof(buf),__VA_ARGS__); \
spdlog::log(loglevel,buf);}while(0);
#ifndef DEBUG
// If we're doing a non-debug build, we want to skip the overhead of
// formatting the string, then calling the logger
#define LOGTRACE(...) ((void)0)
#define LOGDEBUG(...) ((void)0)
#else
#define LOGTRACE(...) SPDLOGWRAPPER(spdlog::level::trace, __VA_ARGS__)
#define LOGDEBUG(...) SPDLOGWRAPPER(spdlog::level::debug, __VA_ARGS__)
#endif
#define LOGINFO(...) SPDLOGWRAPPER(spdlog::level::info, __VA_ARGS__)
#define LOGWARN(...) SPDLOGWRAPPER(spdlog::level::warn, __VA_ARGS__)
#define LOGERROR(...) SPDLOGWRAPPER(spdlog::level::err, __VA_ARGS__)
#define LOGCRITICAL(...) SPDLOGWRAPPER(spdlog::level::critical, __VA_ARGS__)
#endif // log_h

View File

@ -24,7 +24,7 @@
#include "controllers/scsidev_ctrl.h"
#include "controllers/sasidev_ctrl.h"
#include "gpiobus.h"
#include "spdlog/spdlog.h"
//---------------------------------------------------------------------------
//
@ -1064,6 +1064,8 @@ int main(int argc, char* argv[])
struct sched_param schparam;
#endif // BAREMETAL
spdlog::set_level(spdlog::level::trace);
LOGTRACE("Entering the function %s with %d arguments", __PRETTY_FUNCTION__, argc);
// Output the Banner
Banner(argc, argv);

View File

@ -41,18 +41,58 @@ BUS::phase_t FASTCALL BUS::GetPhase()
return GetPhase(mci);
}
//---------------------------------------------------------------------------
//
// Determine Phase String phase enum
//
//---------------------------------------------------------------------------
const char* FASTCALL BUS::GetPhaseStrRaw(phase_t current_phase){
if(current_phase <= phase_t::reserved){
return phase_str_table[current_phase];
}
else
{
return "INVALID";
}
}
//---------------------------------------------------------------------------
//
// Phase Table
// Reference Table 8: https://www.staff.uni-mainz.de/tacke/scsi/SCSI2-06.html
// This determines the phase based upon the Msg, C/D and I/O signals.
//
//---------------------------------------------------------------------------
const BUS::phase_t BUS::phase_table[8] = {
dataout,
datain,
command,
status,
reserved,
reserved,
msgout,
msgin
// | MSG|C/D|I/O |
dataout, // | 0 | 0 | 0 |
datain, // | 0 | 0 | 1 |
command, // | 0 | 1 | 0 |
status, // | 0 | 1 | 1 |
reserved, // | 1 | 0 | 0 |
reserved, // | 1 | 0 | 1 |
msgout, // | 1 | 1 | 0 |
msgin // | 1 | 1 | 1 |
};
//---------------------------------------------------------------------------
//
// Phase Table
// This MUST be kept in sync with the phase_t enum type!
//
//---------------------------------------------------------------------------
const char* BUS::phase_str_table[] = {
"busfree",
"arbitration",
"selection",
"reselection",
"command",
"execute",
"datain",
"dataout",
"status",
"msgin",
"msgout",
"reserved"
};

View File

@ -60,8 +60,14 @@ public:
}
// フェーズ取得
virtual DWORD FASTCALL Aquire() = 0;
// 信号取り込み
static const char* FASTCALL GetPhaseStrRaw(phase_t current_phase);
// Get the string phase name, based upon the raw data
// Extract as specific pin field from a raw data capture
static inline DWORD GetPinRaw(DWORD raw_data, DWORD pin_num)
{
return ((raw_data >> pin_num) & 1);
}
virtual BOOL FASTCALL GetBSY() = 0;
// BSYシグナル取得
@ -125,6 +131,8 @@ public:
private:
static const phase_t phase_table[8];
// フェーズテーブル
static const char* phase_str_table[];
};
#endif // scsi_h