From be3b6d57eda319f9ca3724d57b8abcaaa4f46aa5 Mon Sep 17 00:00:00 2001 From: Josh Dersch Date: Mon, 6 May 2019 19:28:20 +0200 Subject: [PATCH] Implemented AVAILABLE, ERASE, DETERMINE ACCESS PATHS commands. Tweaks to interrupt queueing (request_INTR now blocks until the interrupt actually gets signaled on the unibus). OpenVMS 7.3 now boots on the VAX. --- 10.01_base/2_src/arm/unibusadapter.cpp | 81 ++++++--- 10.01_base/2_src/arm/unibusadapter.hpp | 6 +- 10.02_devices/2_src/mscp_server.cpp | 220 +++++++++++++++++++++---- 10.02_devices/2_src/mscp_server.hpp | 5 +- 10.02_devices/2_src/uda.cpp | 25 +-- 10.03_app_demo/2_src/menu_devices.cpp | 16 +- 6 files changed, 272 insertions(+), 81 deletions(-) diff --git a/10.01_base/2_src/arm/unibusadapter.cpp b/10.01_base/2_src/arm/unibusadapter.cpp index fe136de..7d62e9d 100644 --- a/10.01_base/2_src/arm/unibusadapter.cpp +++ b/10.01_base/2_src/arm/unibusadapter.cpp @@ -92,7 +92,8 @@ irq_request_c::irq_request_c( unsigned level, unsigned vector) : _level(level), - _vector(vector) + _vector(vector), + _isComplete(false) { } @@ -174,13 +175,13 @@ void unibusadapter_c::worker_init_event() { device->on_init_changed(); } + INFO("clearing due to INIT empty %d", _irqRequests.empty()); + // Clear bus request queues - /* pthread_mutex_lock(&_busWorker_mutex); - _dmaRequests.clear(); - _irqRequests.clear(); + while (!_dmaRequests.empty()) _dmaRequests.pop(); + while (!_irqRequests.empty()) _irqRequests.pop(); pthread_mutex_unlock(&_busWorker_mutex); - */ } void unibusadapter_c::worker_power_event() { @@ -194,13 +195,13 @@ void unibusadapter_c::worker_power_event() { device->on_power_changed(); } + INFO("clearing due to power empty %d", _irqRequests.empty()); + // Clear bus request queues - /* pthread_mutex_lock(&_busWorker_mutex); - _dmaRequests.clear(); - _irqRequests.clear(); - pthread_mutex_unlock(&_busWorker_mutex); - */ + while (!_dmaRequests.empty()) _dmaRequests.pop(); + while (!_irqRequests.empty()) _irqRequests.pop(); + pthread_mutex_unlock(&_busWorker_mutex); } // process DATI/DATO access to active device registers @@ -587,11 +588,11 @@ bool unibusadapter_c::request_DMA( void unibusadapter_c::dma_worker() { - + //worker_init_realtime_priority(rt_device); while(true) { dma_request_c* dmaReq = nullptr; - irq_request_c irqReq(0,0); + irq_request_c* irqReq = nullptr; // // Wait for the next request. @@ -610,8 +611,7 @@ void unibusadapter_c::dma_worker() // if (!_irqRequests.empty()) { - irq_request_c const& req = _irqRequests.front(); - irqReq = req; + irqReq = _irqRequests.front(); _irqRequests.pop(); } else @@ -622,16 +622,18 @@ void unibusadapter_c::dma_worker() pthread_mutex_unlock(&_busWorker_mutex); - // Sanity check: Should be no active DMA requests on the PRU. - assert (!request_DMA_active(nullptr)); + // Sanity check: Should be no active DMA or interrupt requests on the PRU. + assert (!request_DMA_active(nullptr) && !request_INTR_active(nullptr)); + /* // If there's an IRQ still active, wait for it to finish. // TODO: find a way to avoid having to do this. timeout_c timer; while (request_INTR_active(nullptr)) { + INFO("intr active"); timer.wait_us(50); - } + } */ if (dmaReq) { @@ -670,7 +672,7 @@ void unibusadapter_c::dma_worker() // Wait for the transfer to complete. // TODO: we're polling the mailbox; is there a more efficient way to do this? timeout_c timeout; - while (request_DMA_active(NULL)) + while (request_DMA_active(nullptr)) { timeout.wait_us(50); } @@ -691,8 +693,14 @@ void unibusadapter_c::dma_worker() dmaReq->SetUnibusEndAddr(mailbox->dma.cur_addr); dmaReq->SetSuccess(mailbox->dma.cur_status == DMA_STATE_READY); - assert(dmaReq->GetUnibusAddr() + dmaReq->GetWordCount() * 2 == mailbox->dma.cur_addr + 2); + if(dmaReq->GetUnibusAddr() + dmaReq->GetWordCount() * 2 != mailbox->dma.cur_addr + 2) + { + FATAL("PRU end addr 0x%x, expected 0x%x", + mailbox->dma.cur_addr + 2, + dmaReq->GetUnibusAddr() + dmaReq->GetWordCount() * 2); + } + // // Signal that the request is complete. // @@ -704,7 +712,7 @@ void unibusadapter_c::dma_worker() else { // Handle interrupt request - switch(irqReq.GetInterruptLevel()) + switch(irqReq->GetInterruptLevel()) { case 4: mailbox->intr.priority_bit = ARBITRATION_PRIORITY_BIT_B4; @@ -723,15 +731,30 @@ void unibusadapter_c::dma_worker() break; default: - ERROR("Request_INTR(): Illegal priority %u, aborting", irqReq.GetInterruptLevel()); + ERROR("Request_INTR(): Illegal priority %u, aborting", irqReq->GetInterruptLevel()); return; } - - mailbox->intr.vector = irqReq.GetVector(); + + mailbox->intr.vector = irqReq->GetVector(); // start! mailbox->arm2pru_req = ARM2PRU_INTR; // PRU now changes state + + // Signal that the request has been raised. + pthread_mutex_lock(&_busWorker_mutex); + irqReq->SetComplete(); + pthread_cond_signal(&_requestFinished_cond); + pthread_mutex_unlock(&_busWorker_mutex); + + // Wait for the transfer to complete. + // TODO: we're polling the mailbox; is there a more efficient way to + // do this? (as w/dma) + timeout_c timeout; + while(request_INTR_active(nullptr)) + { + timeout.wait_us(50); + } } } } @@ -746,10 +769,20 @@ void unibusadapter_c::request_INTR(uint32_t level, uint32_t vector) { vector); pthread_mutex_lock(&_busWorker_mutex); - _irqRequests.push(request); + _irqRequests.push(&request); pthread_cond_signal(&_busWakeup_cond); pthread_mutex_unlock(&_busWorker_mutex); + // + // Wait for request to finish. + // + pthread_mutex_lock(&_busWorker_mutex); + while (!request.IsComplete()) + { + pthread_cond_wait(&_requestFinished_cond, &_busWorker_mutex); + } + pthread_mutex_unlock(&_busWorker_mutex); + // // And we're done. // diff --git a/10.01_base/2_src/arm/unibusadapter.hpp b/10.01_base/2_src/arm/unibusadapter.hpp index 5de5821..d902c1b 100644 --- a/10.01_base/2_src/arm/unibusadapter.hpp +++ b/10.01_base/2_src/arm/unibusadapter.hpp @@ -80,10 +80,14 @@ public: uint32_t GetInterruptLevel() { return _level; } uint32_t GetVector() { return _vector; } + bool IsComplete() { return _isComplete; } + + void SetComplete() { _isComplete = true; } private: uint32_t _level; uint32_t _vector; + bool _isComplete; }; @@ -126,7 +130,7 @@ public: private: std::queue _dmaRequests; - std::queue _irqRequests; + std::queue _irqRequests; pthread_t _busWorker_pthread; pthread_cond_t _busWakeup_cond; pthread_cond_t _requestFinished_cond; diff --git a/10.02_devices/2_src/mscp_server.cpp b/10.02_devices/2_src/mscp_server.cpp index 3f2a506..a256422 100644 --- a/10.02_devices/2_src/mscp_server.cpp +++ b/10.02_devices/2_src/mscp_server.cpp @@ -156,7 +156,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, @@ -169,6 +169,18 @@ mscp_server::Poll(void) switch (header->Word3.Command.Opcode) { + case Opcodes::AVAILABLE: + cmdStatus = Available(message, header->UnitNumber, header->Word3.Command.Modifiers); + break; + + case Opcodes::DETERMINE_ACCESS_PATHS: + cmdStatus = DetermineAccessPaths(message, header->UnitNumber); + break; + + case Opcodes::ERASE: + cmdStatus = Erase(message, header->UnitNumber, header->Word3.Command.Modifiers); + break; + case Opcodes::GET_UNIT_STATUS: cmdStatus = GetUnitStatus(message, header->UnitNumber, header->Word3.Command.Modifiers); break; @@ -198,7 +210,7 @@ mscp_server::Poll(void) break; } - DEBUG("cmd 0x%x st 0x%x fl 0x%x", cmdStatus, GET_STATUS(cmdStatus), GET_FLAGS(cmdStatus)); + INFO("cmd 0x%x st 0x%x fl 0x%x", cmdStatus, GET_STATUS(cmdStatus), GET_FLAGS(cmdStatus)); // // Set the endcode and status bits @@ -241,18 +253,15 @@ mscp_server::Poll(void) message->Word1.Info.Credits = 0; } - //timer.wait_us(250); // // Post the response to the port's response ring. // - if(!_port->PostResponse(message.get())) - { - FATAL("no room at the inn."); - } + if(!_port->PostResponse(message.get())) + { + FATAL("no room at the inn."); + } - // Hack: give interrupts time to settle before doing another transfer. - //timer.wait_us(2500); // // Go around and pick up the next one. @@ -282,6 +291,116 @@ mscp_server::Poll(void) DEBUG("MSCP Polling thread exiting."); } +uint32_t +mscp_server::Available( + shared_ptr message, + uint16_t unitNumber, + uint16_t modifiers) +{ + // Message has no message-specific data. + // We don't do much with this now... + // Just set the specified drive as Available if appropriate. + // We do nothing with the spin-down modifier. + + INFO("MSCP AVAILABLE"); + + mscp_drive_c* drive = GetDrive(unitNumber); + + if (nullptr == drive || + !drive->IsAvailable()) + { + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); + } + + drive->SetOffline(); + + return STATUS(Status::SUCCESS, 0x40, 0); // still connected +} + +uint32_t +mscp_server::DetermineAccessPaths( + shared_ptr message, + uint16_t unitNumber) +{ + INFO("MSCP DETERMINE ACCESS PATHS drive %d", unitNumber); + + // "This command must be treated as a no-op that always succeeds + // if the unit is incapable of being connected to more than one + // controller." That's us! + + return STATUS(Status::SUCCESS, 0, 0); +} + +uint32_t +mscp_server::Erase( + shared_ptr message, + uint16_t unitNumber, + uint16_t modifiers) +{ + #pragma pack(push,1) + struct EraseParameters + { + uint32_t ByteCount; + uint32_t Unused0; + uint32_t Unused1; + uint32_t Unused2; + uint32_t LBN; + }; + #pragma pack(pop) + + // TODO: Factor this code out (shared w/Read and Write) + EraseParameters* params = + reinterpret_cast(GetParameterPointer(message)); + + INFO ("MSCP ERASE unit %d chan count %d lbn %d", + unitNumber, + params->ByteCount, + params->LBN); + + // Adjust message length for response + message->MessageLength = sizeof(EraseParameters) + + HEADER_SIZE; + + mscp_drive_c* drive = GetDrive(unitNumber); + + // Check unit + if (nullptr == drive || + !drive->IsAvailable()) + { + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); + } + + // Check LBN + if (params->LBN > drive->GetBlockCount() + 1) // + 1 for RCT + { + return STATUS(Status::INVALID_COMMAND + (0x1c << 8), 0, 0); // TODO: set sub-code + } + + // Check byte count + if (params->ByteCount > ((drive->GetBlockCount() + 1) - params->LBN) * drive->GetBlockSize()) + { + return STATUS(Status::INVALID_COMMAND + (0x0c << 8), 0, 0); // TODO: as above + } + + // + // OK: do the transfer from a zero'd out buffer to disk + // + unique_ptr memBuffer(new uint8_t[params->ByteCount]); + memset(reinterpret_cast(memBuffer.get()), 0, params->ByteCount); + + drive->Write(params->LBN, + params->ByteCount, + memBuffer.get()); + + // Set parameters for response. + // We leave ByteCount as is (for now anyway) + // And set First Bad Block to 0. (This is unnecessary since we're + // not reporting a bad block, but we're doing it for completeness.) + params->LBN = 0; + + return STATUS(Status::SUCCESS, 0, 0); +} + uint32_t mscp_server::GetUnitStatus( shared_ptr message, @@ -311,26 +430,55 @@ mscp_server::GetUnitStatus( // Adjust message length for response message->MessageLength = sizeof(GetUnitStatusResponseParameters) + HEADER_SIZE; - + + + ControlMessageHeader* header = + reinterpret_cast(message->Message); + + if (modifiers & 0x1) + { + // Next Unit modifier: return the next known unit >= unitNumber. + // Unless unitNumber is greater than the number of drives we support + // we just return the unit specified by unitNumber. + if (unitNumber >= _port->GetDriveCount()) + { + // In this case we act as if drive 0 was queried. + unitNumber = 0; + header->UnitNumber = 0; + } + } mscp_drive_c* drive = GetDrive(unitNumber); - if (nullptr == drive || - !drive->IsAvailable()) - { - INFO("Returning UNIT OFFLINE"); - return STATUS(Status::UNIT_OFFLINE, 3); // unknown -- todo move to enum - } - GetUnitStatusResponseParameters* params = reinterpret_cast( GetParameterPointer(message)); + if (nullptr == drive) + { + // No such drive + params->UnitIdentifier = 0; + params->ShadowUnit = 0; + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); // offline; unknown unit. + } + + if(!drive->IsAvailable()) + { + // Known drive, but offline. + params->UnitIdentifier = 0; + params->ShadowUnit = 0; + + return STATUS(Status::UNIT_OFFLINE, 0x23, 0); // offline; no volume available + } + + params->Reserved0 = 0; + params->Reserved1 = 0; + params->Reserved2 = 0; params->UnitFlags = 0; // TODO: 0 for now, which is sane. params->MultiUnitCode = 0; // Controller dependent, we don't support multi-unit drives. params->UnitIdentifier = drive->GetUnitID(); params->MediaTypeIdentifier = drive->GetMediaID(); - params->ShadowUnit = unitNumber; // Always equal to unit number + params->ShadowUnit = 0; // Always equal to unit number // // For group, and cylinder size we return 0 -- this is appropriate for the @@ -351,11 +499,11 @@ mscp_server::GetUnitStatus( if (drive->IsOnline()) { - return STATUS(Status::SUCCESS, 0); + return STATUS(Status::SUCCESS, 0, 0); } else { - return STATUS(Status::UNIT_AVAILABLE, 0); + return STATUS(Status::UNIT_AVAILABLE, 0, 0); } } @@ -416,7 +564,7 @@ mscp_server::Online( !drive->IsAvailable()) { INFO("Returning UNIT OFFLINE"); - return STATUS(Status::UNIT_OFFLINE, 3); // unknown -- todo move to enum + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); // unknown -- todo move to enum } bool alreadyOnline = drive->IsOnline(); @@ -437,7 +585,7 @@ mscp_server::Online( params->Reserved1 = 0; return STATUS(Status::SUCCESS | - (alreadyOnline ? SuccessSubcodes::ALREADY_ONLINE : SuccessSubcodes::NORMAL), 0); + (alreadyOnline ? SuccessSubcodes::ALREADY_ONLINE : SuccessSubcodes::NORMAL), 0, 0); } uint32_t @@ -470,7 +618,7 @@ mscp_server::SetControllerCharacteristics( // if (params->MSCPVersion != 0) { - return STATUS(Status::INVALID_COMMAND, 0); // TODO: set sub-status + return STATUS(Status::INVALID_COMMAND, 0, 0); // TODO: set sub-status } else { @@ -486,7 +634,7 @@ mscp_server::SetControllerCharacteristics( params->HostTimeout = 0xff; // Controller timeout: return the max value. params->TimeAndDate = _port->GetControllerIdentifier(); // Controller ID - return STATUS(Status::SUCCESS, 0); + return STATUS(Status::SUCCESS, 0, 0); } } @@ -540,7 +688,7 @@ mscp_server::SetUnitCharacteristics( !drive->IsAvailable()) { INFO("Returning UNIT OFFLINE"); - return STATUS(Status::UNIT_OFFLINE, 3); + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); } SetUnitCharacteristicsResponseParameters* params = @@ -554,7 +702,7 @@ mscp_server::SetUnitCharacteristics( params->UnitSize = drive->GetBlockCount(); params->VolumeSerialNumber = 0; // We report no serial - return STATUS(Status::SUCCESS, 0); + return STATUS(Status::SUCCESS, 0, 0); } @@ -578,7 +726,7 @@ mscp_server::Read( ReadParameters* params = reinterpret_cast(GetParameterPointer(message)); - DEBUG("MSCP READ unit %d chan o%o pa o%o count %d lbn %d", + INFO ("MSCP READ unit %d chan o%o pa o%o count %d lbn %d", unitNumber, params->BufferPhysicalAddress >> 24, params->BufferPhysicalAddress & 0x00ffffff, @@ -595,7 +743,7 @@ mscp_server::Read( if (nullptr == drive || !drive->IsAvailable()) { - return STATUS(Status::UNIT_OFFLINE, 3); + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); } // TODO: Need to rectify reads/writes to RCT area more cleanly @@ -604,12 +752,12 @@ mscp_server::Read( // Check LBN and byte count if (params->LBN >= drive->GetBlockCount() + 1) // + 1 for RCT write protect flag { - return STATUS(Status::INVALID_COMMAND + (0x1c << 8), 0); // TODO: set sub-code + return STATUS(Status::INVALID_COMMAND + (0x1c << 8), 0, 0); // TODO: set sub-code } if (params->ByteCount > ((drive->GetBlockCount() + 1) - params->LBN) * drive->GetBlockSize()) { - return STATUS(Status::INVALID_COMMAND + (0xc << 8), 0); // TODO: as above + return STATUS(Status::INVALID_COMMAND + (0xc << 8), 0, 0); // TODO: as above } // @@ -628,7 +776,7 @@ mscp_server::Read( // not reporting a bad block, but we're doing it for completeness.) params->LBN = 0; - return STATUS(Status::SUCCESS,0); + return STATUS(Status::SUCCESS, 0, 0); } uint32_t @@ -652,7 +800,7 @@ mscp_server::Write( WriteParameters* params = reinterpret_cast(GetParameterPointer(message)); - DEBUG("MSCP WRITE unit %d chan o%o pa o%o count %d lbn %d", + INFO ("MSCP WRITE unit %d chan o%o pa o%o count %d lbn %d", unitNumber, params->BufferPhysicalAddress >> 24, params->BufferPhysicalAddress & 0x00ffffff, @@ -669,19 +817,19 @@ mscp_server::Write( if (nullptr == drive || !drive->IsAvailable()) { - return STATUS(Status::UNIT_OFFLINE, 3); + return STATUS(Status::UNIT_OFFLINE, 0x3, 0); } // Check LBN if (params->LBN > drive->GetBlockCount() + 1) // + 1 for RCT { - return STATUS(Status::INVALID_COMMAND + (0x1c << 8), 0); // TODO: set sub-code + return STATUS(Status::INVALID_COMMAND + (0x1c << 8), 0, 0); // TODO: set sub-code } // Check byte count if (params->ByteCount > ((drive->GetBlockCount() + 1) - params->LBN) * drive->GetBlockSize()) { - return STATUS(Status::INVALID_COMMAND + (0x0c << 8), 0); // TODO: as above + return STATUS(Status::INVALID_COMMAND + (0x0c << 8), 0, 0); // TODO: as above } // @@ -702,7 +850,7 @@ mscp_server::Write( // not reporting a bad block, but we're doing it for completeness.) params->LBN = 0; - return STATUS(Status::SUCCESS,0); + return STATUS(Status::SUCCESS, 0, 0); } uint8_t* diff --git a/10.02_devices/2_src/mscp_server.hpp b/10.02_devices/2_src/mscp_server.hpp index 571bfe1..9110ea4 100644 --- a/10.02_devices/2_src/mscp_server.hpp +++ b/10.02_devices/2_src/mscp_server.hpp @@ -9,7 +9,7 @@ class mscp_drive_c; // Builds a uint32_t containing the status, flags, and endcode for a response message, // used to simplify returning the appropriate status bits from command functions. -#define STATUS(status, flags) ((flags) << 8) | ((status) << 16) +#define STATUS(status, modifier, flags) ((flags) << 8) | (((status) | ((modifier) * 0x20)) << 16) #define GET_STATUS(status) (((status) >> 16) & 0xffff) #define GET_FLAGS(status) (((status) >> 8) & 0xff) @@ -134,6 +134,9 @@ public: bool on_param_changed(parameter_c *param) override { return true; } private: + uint32_t Available(std::shared_ptr message, uint16_t unitNumber, uint16_t modifiers); + uint32_t DetermineAccessPaths(std::shared_ptr message, uint16_t unitNumber); + uint32_t Erase(std::shared_ptr message, uint16_t unitNumber, uint16_t modifiers); uint32_t GetUnitStatus(std::shared_ptr message, uint16_t unitNumber, uint16_t modifiers); uint32_t Online(std::shared_ptr message, uint16_t unitNumber, uint16_t modifiers); uint32_t SetControllerCharacteristics(std::shared_ptr message); diff --git a/10.02_devices/2_src/uda.cpp b/10.02_devices/2_src/uda.cpp index 60c1665..d635399 100644 --- a/10.02_devices/2_src/uda.cpp +++ b/10.02_devices/2_src/uda.cpp @@ -148,7 +148,7 @@ void uda_c::worker(void) case InitializationStep::Step1: // Wait 100uS, set SA. - timeout.wait_us(100); + timeout.wait_ms(100); INFO("Transition to Init state S1."); // @@ -162,10 +162,8 @@ void uda_c::worker(void) break; case InitializationStep::Step2: - // Wait 100uS, set SA. - timeout.wait_ms(100); - INFO("Transition to Init state S2."); + timeout.wait_ms(1000); // 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. @@ -176,7 +174,7 @@ void uda_c::worker(void) case InitializationStep::Step3: // Wait 100uS, set SA. - timeout.wait_ms(100); + timeout.wait_ms(1000); INFO("Transition to Init state S3."); // Update the SA read value for step 3: @@ -187,6 +185,7 @@ void uda_c::worker(void) break; case InitializationStep::Step4: + timeout.wait_ms(100); // Clear communications area, set SA INFO("Clearing comm area at 0x%x.", _ringBase); @@ -195,10 +194,10 @@ void uda_c::worker(void) // 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) + 4; + i < (_responseRingLength + _commandRingLength) * sizeof(Descriptor) + 6; i += 2) { - DMAWriteWord(_ringBase + i - 4, 0x0); + DMAWriteWord(_ringBase + i - 6, 0x0); } // @@ -225,7 +224,7 @@ void uda_c::worker(void) // _sa = 0x4063; //UDA50 _sa = 0x4042; update_SA(); - Interrupt(); + Interrupt(); break; case InitializationStep::Complete: @@ -317,7 +316,8 @@ uda_c::on_after_register_access( // be generated during normal operation and, if IE=1, // during initialization. _step1Value = value; - intr_vector.value = _interruptVector = (value & 0x7f) << 2; + + intr_vector.value = _interruptVector = ((value & 0x7f) << 2); _interruptEnable = !!(value & 0x80); _responseRingLength = (1 << ((value & 0x700) >> 8)); _commandRingLength = (1 << ((value & 0x3800) >> 11)); @@ -325,6 +325,8 @@ uda_c::on_after_register_access( 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); // Move to step 2. StateTransition(InitializationStep::Step2); @@ -344,7 +346,7 @@ uda_c::on_after_register_access( _ringBase = value & 0xfffe; _purgeInterruptEnable = !!(value & 0x1); - INFO("Step2: 0x%x", value); + INFO("Step2: rb 0x%x pi %d", _ringBase, _purgeInterruptEnable); // Move to step 3 and interrupt as necessary. StateTransition(InitializationStep::Step3); break; @@ -363,7 +365,7 @@ uda_c::on_after_register_access( // [ringbase+0]. _ringBase |= ((value & 0x7fff) << 16); - INFO("Step3: 0x%x", value); + INFO("Step3: ringbase 0x%x", _ringBase); // Move to step 4 and interrupt as necessary. StateTransition(InitializationStep::Step4); break; @@ -740,6 +742,7 @@ uda_c::Interrupt(void) { if (_interruptEnable && _interruptVector != 0) { + INFO("interrupt"); interrupt(); } } diff --git a/10.03_app_demo/2_src/menu_devices.cpp b/10.03_app_demo/2_src/menu_devices.cpp index 4078925..ea3f341 100644 --- a/10.03_app_demo/2_src/menu_devices.cpp +++ b/10.03_app_demo/2_src/menu_devices.cpp @@ -78,7 +78,7 @@ void menus_c::menu_devices(void) { // cpu_c cpu; // create RL11 + drives - RL11_c RL11; // instantiates also 4 RL01/02 drives + // RL11_c RL11; // instantiates also 4 RL01/02 drives cur_device = NULL; paneldriver->reset(); // reset I2C, restart worker() @@ -95,9 +95,9 @@ void menus_c::menu_devices(void) { //demo_regs.install(); //demo_regs.worker_start(); - RL11.install(); - RL11.connect_to_panel(); - RL11.worker_start(); + //RL11.install(); + //RL11.connect_to_panel(); + //RL11.worker_start(); RK05.install(); RK05.worker_start(); @@ -344,11 +344,11 @@ void menus_c::menu_devices(void) { //RL11.disconnect_from_panel(); //RL11.uninstall(); - RK05.worker_stop(); - RK05.uninstall(); + // RK05.worker_stop(); + // RK05.uninstall(); - // UDA50.worker_stop(); - // UDA50.uninstall(); + UDA50.worker_stop(); + UDA50.uninstall(); //demo_regs.worker_stop(); //demo_regs.uninstall();