1
0
mirror of https://github.com/livingcomputermuseum/UniBone.git synced 2026-01-28 04:47:46 +00:00

Changed reset behavior; now done asynchronously. (Was taking too long, especially during resets due to IP regsister read).

RSX-11M now boots and runs.
This commit is contained in:
Josh Dersch
2019-05-11 02:10:12 +02:00
parent bb546db52a
commit 464049f0b6
3 changed files with 42 additions and 53 deletions

View File

@@ -24,7 +24,7 @@ mscp_drive_c::mscp_drive_c(
// Calculate the unit's ID:
// drive number in upper 32 bits, class/model in lower.
_unitID = (static_cast<uint64_t>(driveNumber) << 32) | 0x02020000;
_unitID = (static_cast<uint64_t>(driveNumber + 1) << 32) | 0x02020000;
// Initialize the RCT area
_rctData.reset(new uint8_t[GetBlockSize()]);

View File

@@ -184,7 +184,7 @@ mscp_server::Poll(void)
ControlMessageHeader* header =
reinterpret_cast<ControlMessageHeader*>(message->Message);
INFO ("Message size 0x%x opcode 0x%x rsvd 0x%x mod 0x%x unit %d, ursvd 0x%x, ref 0x%x",
DEBUG("Message size 0x%x opcode 0x%x rsvd 0x%x mod 0x%x unit %d, ursvd 0x%x, ref 0x%x",
message->MessageLength,
header->Word3.Command.Opcode,
header->Word3.Command.Reserved,
@@ -302,7 +302,6 @@ mscp_server::Poll(void)
message->Word1.Info.Credits = 0;
}
//
// Post the response to the port's response ring.
//
@@ -709,7 +708,7 @@ mscp_server::SetControllerCharacteristics(
reinterpret_cast<SetControllerCharacteristicsParameters*>(
GetParameterPointer(message));
INFO ("MSCP SET CONTROLLER CHARACTERISTICS");
DEBUG("MSCP SET CONTROLLER CHARACTERISTICS");
// Adjust message length for response
message->MessageLength = sizeof(SetControllerCharacteristicsParameters) +
@@ -724,7 +723,6 @@ mscp_server::SetControllerCharacteristics(
}
else
{
INFO("version 0x%x controller flags 0x%x", params->MSCPVersion, params->ControllerFlags);
_hostTimeout = params->HostTimeout;
_controllerFlags = params->ControllerFlags;

View File

@@ -88,24 +88,19 @@ uda_c::~uda_c()
void uda_c::Reset(void)
{
INFO("UDA reset");
DEBUG("UDA reset");
_server->Reset();
_ringBase = 0;
//_commandRingLength = 0;
//_responseRingLength = 0;
_commandRingLength = 0;
_responseRingLength = 0;
_commandRingPointer = 0;
_responseRingPointer = 0;
_interruptVector = 0;
intr_vector.value = 0;
_interruptEnable = false;
_purgeInterruptEnable = false;
_next_step = false;
_server->Reset();
// Signal the worker to begin the initialization sequence.
StateTransition(InitializationStep::Uninitialized);
update_SA(0x0);
}
uint32_t uda_c::GetDriveCount(void)
@@ -133,7 +128,7 @@ void uda_c::StateTransition(
void uda_c::worker(void)
{
worker_init_realtime_priority(rt_max);
worker_init_realtime_priority(rt_device);
timeout_c timeout;
@@ -153,25 +148,24 @@ void uda_c::worker(void)
_next_step = false;
pthread_mutex_unlock(&on_after_register_access_mutex);
// INFO("Awoken.");
switch (_initStep)
{
case InitializationStep::Uninitialized:
INFO("Transition to Init state Uninitialized.");
DEBUG("Transition to Init state Uninitialized.");
// SA should already be zero but we'll be extra sure here.
update_SA(0x0);
timeout.wait_ms(500);
// Reset the controller: This may take some time as we must
// wait for the MSCP server to wrap up its current workitem.
Reset();
StateTransition(InitializationStep::Step1);
break;
case InitializationStep::Step1:
// Wait 100uS, set SA.
timeout.wait_ms(500);
timeout.wait_us(500);
INFO("Transition to Init state S1.");
DEBUG("Transition to Init state S1.");
//
// S1 is set, all other bits zero. This indicates that we
// support a host-settable interrupt vector, that we do not
@@ -182,8 +176,8 @@ void uda_c::worker(void)
break;
case InitializationStep::Step2:
INFO("Transition to Init state S2.");
timeout.wait_ms(500);
DEBUG("Transition to Init state S2.");
timeout.wait_us(500);
// update the SA read value for step 2:
// S2 is set, unibus port type (0), SA bits 15-8 written
// by the host in step 1.
@@ -193,9 +187,9 @@ void uda_c::worker(void)
case InitializationStep::Step3:
// Wait 100uS, set SA.
timeout.wait_ms(500);
timeout.wait_us(500);
INFO("Transition to Init state S3.");
DEBUG("Transition to Init state S3.");
// Update the SA read value for step 3:
// S3 set, plus SA bits 7-0 written by the host in step 1.
update_SA(0x2000 | (_step1Value & 0xff));
@@ -206,8 +200,8 @@ void uda_c::worker(void)
timeout.wait_us(100);
// Clear communications area, set SA
INFO("Clearing comm area at 0x%x. Purge header: %d", _ringBase, _purgeInterruptEnable);
INFO("resp 0x%x comm 0x%x", _responseRingLength, _commandRingLength);
DEBUG("Clearing comm area at 0x%x. Purge header: %d", _ringBase, _purgeInterruptEnable);
DEBUG("resp 0x%x comm 0x%x", _responseRingLength, _commandRingLength);
{
int headerSize = _purgeInterruptEnable ? 8 : 4;
@@ -236,7 +230,7 @@ void uda_c::worker(void)
reinterpret_cast<uint8_t*>(&blankDescriptor));
}
INFO("Transition to Init state S4, comm area initialized.");
DEBUG("Transition to Init state S4, comm area initialized.");
// Update the SA read value for step 4:
// Bits 7-0 indicating our control microcode version.
update_SA(0x4063); // UDA50 ID, makes RSTS happy
@@ -244,9 +238,8 @@ void uda_c::worker(void)
break;
case InitializationStep::Complete:
INFO("Initialization complete.");
DEBUG("Initialization complete.");
break;
}
}
}
@@ -266,7 +259,7 @@ uda_c::on_after_register_access(
// "When written with any value, it causes a hard initialization
// of the port and the device controller."
DEBUG("Reset due to IP read");
Reset();
StateTransition(InitializationStep::Uninitialized);
}
else
{
@@ -287,7 +280,7 @@ uda_c::on_after_register_access(
{
case InitializationStep::Uninitialized:
// Should not occur, we treat it like step1 here.
INFO("Write to SA in Uninitialized state.");
DEBUG("Write to SA in Uninitialized state.");
case InitializationStep::Step1:
// Host writes the following:
@@ -318,11 +311,11 @@ uda_c::on_after_register_access(
_responseRingLength = (1 << ((value & 0x700) >> 8));
_commandRingLength = (1 << ((value & 0x3800) >> 11));
INFO("Step1: 0x%x", value);
INFO("resp ring 0x%x", _responseRingLength);
INFO("cmd ring 0x%x", _commandRingLength);
INFO("vector 0x%x", _interruptVector);
INFO("ie %d", _interruptEnable);
DEBUG("Step1: 0x%x", value);
DEBUG("resp ring 0x%x", _responseRingLength);
DEBUG("cmd ring 0x%x", _commandRingLength);
DEBUG("vector 0x%x", _interruptVector);
DEBUG("ie %d", _interruptEnable);
// Move to step 2.
StateTransition(InitializationStep::Step2);
@@ -342,7 +335,7 @@ uda_c::on_after_register_access(
_ringBase = value & 0xfffe;
_purgeInterruptEnable = !!(value & 0x1);
INFO("Step2: rb 0x%x pi %d", _ringBase, _purgeInterruptEnable);
DEBUG("Step2: rb 0x%x pi %d", _ringBase, _purgeInterruptEnable);
// Move to step 3 and interrupt as necessary.
StateTransition(InitializationStep::Step3);
break;
@@ -361,7 +354,7 @@ uda_c::on_after_register_access(
// [ringbase+0].
_ringBase |= ((value & 0x7fff) << 16);
INFO("Step3: ringbase 0x%x", _ringBase);
DEBUG("Step3: ringbase 0x%x", _ringBase);
// Move to step 4 and interrupt as necessary.
StateTransition(InitializationStep::Step4);
break;
@@ -394,7 +387,7 @@ uda_c::on_after_register_access(
// supporting onboard diagnostics and there's nothing to
// report.
//
INFO("Step4: 0x%x", value);
DEBUG("Step4: 0x%x", value);
if (value & 0x1)
{
//
@@ -417,7 +410,7 @@ uda_c::on_after_register_access(
// operation, it signals the port that the host has successfully
// completed a bus adapter purge in response to a port-initiated
// purge request.
// Unsure what this means at the moment.
// We don't deal with bus adapter purges, yet.
break;
}
break;
@@ -481,8 +474,6 @@ uda_c::GetNextCommand(void)
messageAddress - 4,
success);
// INFO("Message length 0x%x", messageLength);
//
// TODO: sanity check message length (what is the max length we
// can expect to see?)
@@ -558,7 +549,7 @@ uda_c::GetNextCommand(void)
//
DMAWriteWord(
_ringBase - 4,
0xffff);
0x1);
//
// Raise the interrupt
@@ -624,13 +615,13 @@ uda_c::PostResponse(
if (reinterpret_cast<uint16_t*>(response)[0] == 0)
{
INFO("Writing zero length response!");
ERROR("Writing zero length response!");
}
if (messageLength < response->MessageLength)
{
// TODO: handle this; for now eat flaming death.
INFO("Response buffer %x > message length %x", response->MessageLength, messageLength);
// TODO: A lot of bootstraps appear to set up response buffers of length 0...
ERROR("Response buffer %x > message length %x", response->MessageLength, messageLength);
}
// else
{
@@ -701,13 +692,13 @@ uda_c::PostResponse(
// Post an interrupt as necessary.
if (doInterrupt)
{
// INFO("Response ring no longer empty, interrupting.");
DEBUG("Response ring no longer empty, interrupting.");
//
// Set ring base - 2 to non-zero to indicate a transition.
//
DMAWriteWord(
_ringBase - 2,
0xffff);
0x1);
//
// Raise the interrupt
@@ -749,7 +740,7 @@ uda_c::on_power_changed(void)
if (power_down)
{
DEBUG("Reset due to power change");
Reset();
StateTransition(InitializationStep::Uninitialized);
}
}
@@ -759,7 +750,7 @@ uda_c::on_init_changed(void)
if (init_asserted)
{
DEBUG("Reset due to INIT");
Reset();
StateTransition(InitializationStep::Uninitialized);
}
storagecontroller_c::on_init_changed();