From 22be88832c65a1aa63823fec57e6f94efa6cfd1a Mon Sep 17 00:00:00 2001 From: Josh Dersch Date: Thu, 9 May 2019 02:00:05 +0200 Subject: [PATCH] Tweaks to MSCP initialization, some cleanup. --- 10.02_devices/2_src/mscp_server.cpp | 9 ++-- 10.02_devices/2_src/uda.cpp | 81 +++++++++-------------------- 10.02_devices/2_src/uda.hpp | 11 ++-- 3 files changed, 34 insertions(+), 67 deletions(-) diff --git a/10.02_devices/2_src/mscp_server.cpp b/10.02_devices/2_src/mscp_server.cpp index a95d06b..54ce9de 100644 --- a/10.02_devices/2_src/mscp_server.cpp +++ b/10.02_devices/2_src/mscp_server.cpp @@ -184,7 +184,7 @@ mscp_server::Poll(void) ControlMessageHeader* header = reinterpret_cast(message->Message); - DEBUG("Message size 0x%x opcode 0x%x rsvd 0x%x mod 0x%x unit %d, ursvd 0x%x, ref 0x%x", + INFO ("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, @@ -542,7 +542,7 @@ mscp_server::GetUnitStatus( if(!drive->IsAvailable()) { - // Known drive, but offline. + // Known drive, but not available at this time. params->UnitIdentifier = 0; params->ShadowUnit = 0; @@ -556,7 +556,7 @@ mscp_server::GetUnitStatus( params->MultiUnitCode = 0; // Controller dependent, we don't support multi-unit drives. params->UnitIdentifier = drive->GetUnitID(); params->MediaTypeIdentifier = drive->GetMediaID(); - params->ShadowUnit = 0; // Always equal to unit number + params->ShadowUnit = unitNumber; // Always equal to unit number // // For group, and cylinder size we return 0 -- this is appropriate for the @@ -709,7 +709,7 @@ mscp_server::SetControllerCharacteristics( reinterpret_cast( GetParameterPointer(message)); - DEBUG("MSCP SET CONTROLLER CHARACTERISTICS"); + INFO ("MSCP SET CONTROLLER CHARACTERISTICS"); // Adjust message length for response message->MessageLength = sizeof(SetControllerCharacteristicsParameters) + @@ -724,6 +724,7 @@ mscp_server::SetControllerCharacteristics( } else { + INFO("version 0x%x controller flags 0x%x", params->MSCPVersion, params->ControllerFlags); _hostTimeout = params->HostTimeout; _controllerFlags = params->ControllerFlags; diff --git a/10.02_devices/2_src/uda.cpp b/10.02_devices/2_src/uda.cpp index 3bf85fd..392f05c 100644 --- a/10.02_devices/2_src/uda.cpp +++ b/10.02_devices/2_src/uda.cpp @@ -21,7 +21,6 @@ uda_c::uda_c() : storagecontroller_c(), - _sa(0), _server(nullptr), _ringBase(0), _commandRingLength(0), @@ -92,8 +91,8 @@ void uda_c::Reset(void) INFO("UDA reset"); _ringBase = 0; - _commandRingLength = 0; - _responseRingLength = 0; + //_commandRingLength = 0; + //_responseRingLength = 0; _commandRingPointer = 0; _responseRingPointer = 0; _interruptVector = 0; @@ -106,9 +105,7 @@ void uda_c::Reset(void) // Signal the worker to begin the initialization sequence. StateTransition(InitializationStep::Uninitialized); - - _sa = 0; - update_SA(); + update_SA(0x0); } uint32_t uda_c::GetDriveCount(void) @@ -164,15 +161,15 @@ void uda_c::worker(void) INFO("Transition to Init state Uninitialized."); // SA should already be zero but we'll be extra sure here. - _sa = 0; - update_SA(); + update_SA(0x0); + timeout.wait_ms(500); StateTransition(InitializationStep::Step1); break; case InitializationStep::Step1: // Wait 100uS, set SA. - timeout.wait_us(1000); + timeout.wait_ms(500); INFO("Transition to Init state S1."); // @@ -181,30 +178,27 @@ void uda_c::worker(void) // implement enhanced diagnostics, and that no errors have // occurred. // - _sa = 0x0800; - update_SA(); + update_SA(0x0800); break; case InitializationStep::Step2: INFO("Transition to Init state S2."); - timeout.wait_us(1000); + timeout.wait_ms(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. - _sa = 0x1000 | ((_step1Value >> 8) & 0xff); - update_SA(); + update_SA(0x1000 | ((_step1Value >> 8) & 0xff)); Interrupt(); break; case InitializationStep::Step3: // Wait 100uS, set SA. - timeout.wait_us(1000); + timeout.wait_ms(500); INFO("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. - _sa = 0x2000 | (_step1Value & 0xff); - update_SA(); + update_SA(0x2000 | (_step1Value & 0xff)); Interrupt(); break; @@ -212,23 +206,23 @@ void uda_c::worker(void) timeout.wait_us(100); // Clear communications area, set SA - INFO("Clearing comm area at 0x%x.", _ringBase); + INFO("Clearing comm area at 0x%x. Purge header: %d", _ringBase, _purgeInterruptEnable); INFO("resp 0x%x comm 0x%x", _responseRingLength, _commandRingLength); - // TODO: -6 and -8 are described; do these always get cleared or only - // on VAXen? ZUDJ diag only expects -2 and -4 to be cleared... - for(uint32_t i = 0; - i < (_responseRingLength + _commandRingLength) * sizeof(Descriptor) + 6; - i += 2) { - DMAWriteWord(_ringBase + i - 6, 0x0); + int headerSize = _purgeInterruptEnable ? 8 : 4; + for(uint32_t i = 0; + i < (_responseRingLength + _commandRingLength) * sizeof(Descriptor) + headerSize; + i += 2) + { + DMAWriteWord(_ringBase + i - headerSize, 0x0); + } } // // Set the ownership bit on all descriptors in the response ring // to indicate that the port owns them. // - Descriptor blankDescriptor; blankDescriptor.Word0.Word0 = 0; blankDescriptor.Word1.Word1 = 0; @@ -242,37 +236,15 @@ void uda_c::worker(void) reinterpret_cast(&blankDescriptor)); } - INFO("Transition to Init state S4."); + INFO("Transition to Init state S4, comm area initialized."); // Update the SA read value for step 4: // Bits 7-0 indicating our control microcode version. - // _sa = 0x4063; //UDA50 - _sa = 0x4042; - update_SA(); - Interrupt(); + update_SA(0x4063); // UDA50 ID, makes RSTS happy + Interrupt(); break; case InitializationStep::Complete: - INFO("Transition to Init state Complete. Initializing response ring."); - //_sa = 0x0; - //update_SA(); - - // - // Set the ownership bit on all descriptors in the response ring - // to indicate that the port owns them. - // - /* - Descriptor blankDescriptor; - blankDescriptor.Word0.Word0 = 0; - blankDescriptor.Word1.Word1 = 0; - blankDescriptor.Word1.Fields.Ownership = 1; - - for(uint32_t i = 0; i < _responseRingLength; i++) - { - DMAWrite( - GetResponseDescriptorAddress(i), - sizeof(Descriptor), - reinterpret_cast(&blankDescriptor)); - } */ + INFO("Initialization complete."); break; } @@ -432,8 +404,7 @@ uda_c::on_after_register_access( StateTransition(InitializationStep::Complete); // The VMS bootstrap expects SA to be zero IMMEDIATELY // after completion. - _sa = 0; - update_SA(); + update_SA(0x0); } else { @@ -455,11 +426,11 @@ uda_c::on_after_register_access( } void -uda_c::update_SA() +uda_c::update_SA(uint16_t value) { set_register_dati_value( SA_reg, - _sa, + value, "update_SA"); } diff --git a/10.02_devices/2_src/uda.hpp b/10.02_devices/2_src/uda.hpp index 41ac76f..f33ff83 100644 --- a/10.02_devices/2_src/uda.hpp +++ b/10.02_devices/2_src/uda.hpp @@ -28,9 +28,6 @@ struct Message uint16_t Word1; } Word1; - // 384 bytes is the minimum needed to support - // datagram messages. The underlying buffer will - // be allocated to cover whatever size needed. uint8_t Message[sizeof(ControlMessageHeader)]; }; #pragma pack(pop) @@ -92,14 +89,12 @@ public: uint8_t* DMARead(uint32_t address, size_t lengthInBytes, size_t bufferSize); private: - void update_SA(void); + void update_SA(uint16_t value); // UDA50 registers: unibusdevice_register_t *IP_reg; unibusdevice_register_t *SA_reg; - uint16_t _sa; - std::shared_ptr _server; uint32_t _ringBase; @@ -137,8 +132,8 @@ private: Complete, }; - InitializationStep _initStep; - bool _next_step; + volatile InitializationStep _initStep; + volatile bool _next_step; void StateTransition(InitializationStep nextStep);