mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-04-03 04:19:01 +00:00
Added small workaround for (possible) bug in VMS secondary bootstrap; improved reset behavior.
4.3bsd still panics during uda bringup.
This commit is contained in:
@@ -175,13 +175,9 @@ 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);
|
||||
while (!_dmaRequests.empty()) _dmaRequests.pop();
|
||||
while (!_irqRequests.empty()) _irqRequests.pop();
|
||||
pthread_mutex_unlock(&_busWorker_mutex);
|
||||
rundown_bus_requests();
|
||||
}
|
||||
|
||||
void unibusadapter_c::worker_power_event() {
|
||||
@@ -195,13 +191,8 @@ 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);
|
||||
while (!_dmaRequests.empty()) _dmaRequests.pop();
|
||||
while (!_irqRequests.empty()) _irqRequests.pop();
|
||||
pthread_mutex_unlock(&_busWorker_mutex);
|
||||
rundown_bus_requests();
|
||||
}
|
||||
|
||||
// process DATI/DATO access to active device registers
|
||||
@@ -625,16 +616,6 @@ void unibusadapter_c::dma_worker()
|
||||
// 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)
|
||||
{
|
||||
// We do the DMA transfer in chunks so we can handle arbitrary buffer sizes.
|
||||
@@ -693,14 +674,9 @@ void unibusadapter_c::dma_worker()
|
||||
dmaReq->SetUnibusEndAddr(mailbox->dma.cur_addr);
|
||||
dmaReq->SetSuccess(mailbox->dma.cur_status == DMA_STATE_READY);
|
||||
|
||||
if(dmaReq->GetUnibusAddr() + dmaReq->GetWordCount() * 2 != mailbox->dma.cur_addr + 2)
|
||||
assert(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.
|
||||
//
|
||||
@@ -759,6 +735,33 @@ void unibusadapter_c::dma_worker()
|
||||
}
|
||||
}
|
||||
|
||||
void unibusadapter_c::rundown_bus_requests()
|
||||
{
|
||||
//
|
||||
// Cancel all pending DMA and IRQ requests, freeing threads waiting
|
||||
// on completion.
|
||||
//
|
||||
pthread_mutex_lock(&_busWorker_mutex);
|
||||
while (!_dmaRequests.empty())
|
||||
{
|
||||
dma_request_c* dmaReq = _dmaRequests.front();
|
||||
dmaReq->SetSuccess(false);
|
||||
dmaReq->SetComplete();
|
||||
pthread_cond_signal(&_requestFinished_cond);
|
||||
_dmaRequests.pop();
|
||||
}
|
||||
while (!_irqRequests.empty())
|
||||
{
|
||||
irq_request_c* irqReq = _irqRequests.front();
|
||||
irqReq->SetComplete();
|
||||
pthread_cond_signal(&_requestFinished_cond);
|
||||
_irqRequests.pop();
|
||||
}
|
||||
pthread_mutex_unlock(&_busWorker_mutex);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void unibusadapter_c::request_INTR(uint32_t level, uint32_t vector) {
|
||||
//
|
||||
// Acquire bus mutex; append new request to queue.
|
||||
|
||||
@@ -124,6 +124,7 @@ public:
|
||||
bool request_DMA(uint8_t unibus_control, uint32_t unibus_addr,
|
||||
uint16_t *buffer, uint32_t wordcount);
|
||||
void request_INTR(uint32_t level, uint32_t vector);
|
||||
void rundown_bus_requests(void);
|
||||
|
||||
void print_shared_register_map(void);
|
||||
|
||||
|
||||
@@ -122,9 +122,6 @@ mscp_server::Poll(void)
|
||||
|
||||
pthread_mutex_unlock(&polling_mutex);
|
||||
|
||||
// timer.wait_us(100);
|
||||
|
||||
|
||||
if (_abort_polling)
|
||||
{
|
||||
break;
|
||||
@@ -262,6 +259,14 @@ mscp_server::Poll(void)
|
||||
FATAL("no room at the inn.");
|
||||
}
|
||||
|
||||
//
|
||||
// This delay works around an issue in the VMS bootstrap -- unsure of the
|
||||
// exact cause, it appears to be a race condition exacerbated by the speed
|
||||
// at which we're able to process commands in the ring buffer (we are much
|
||||
// faster than any real MSCP device ever was.)
|
||||
// This is likely a hack, we may be papering over a bug somewhere.
|
||||
//
|
||||
timer.wait_us(100);
|
||||
|
||||
//
|
||||
// Go around and pick up the next one.
|
||||
|
||||
@@ -78,10 +78,7 @@ uda_c::~uda_c()
|
||||
|
||||
void uda_c::Reset(void)
|
||||
{
|
||||
DEBUG("UDA reset");
|
||||
|
||||
_sa = 0;
|
||||
update_SA();
|
||||
INFO("UDA reset");
|
||||
|
||||
_ringBase = 0;
|
||||
_commandRingLength = 0;
|
||||
@@ -94,11 +91,13 @@ void uda_c::Reset(void)
|
||||
_purgeInterruptEnable = false;
|
||||
_next_step = false;
|
||||
|
||||
_server->Reset();
|
||||
|
||||
// Signal the worker to begin the initialization sequence.
|
||||
StateTransition(InitializationStep::Uninitialized);
|
||||
|
||||
_server->Reset();
|
||||
_sa = 0;
|
||||
update_SA();
|
||||
}
|
||||
|
||||
uint32_t uda_c::GetDriveCount(void)
|
||||
@@ -126,7 +125,7 @@ void uda_c::StateTransition(
|
||||
|
||||
void uda_c::worker(void)
|
||||
{
|
||||
worker_init_realtime_priority(rt_device);
|
||||
worker_init_realtime_priority(rt_max);
|
||||
|
||||
timeout_c timeout;
|
||||
|
||||
@@ -862,6 +861,7 @@ uda_c::DMAWrite(
|
||||
uint8_t* buffer)
|
||||
{
|
||||
assert ((lengthInBytes % 2) == 0);
|
||||
assert (address < 0x40000);
|
||||
|
||||
return unibusadapter->request_DMA(
|
||||
UNIBUS_CONTROL_DATO,
|
||||
@@ -883,6 +883,7 @@ uda_c::DMARead(
|
||||
{
|
||||
assert (bufferSize >= lengthInBytes);
|
||||
assert((lengthInBytes % 2) == 0);
|
||||
assert (address < 0x40000);
|
||||
|
||||
uint16_t* buffer = new uint16_t[bufferSize >> 1];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user