mirror of
https://github.com/livingcomputermuseum/UniBone.git
synced 2026-05-03 06:29:28 +00:00
Rewrote lower-level DMA and IRQ handling: DMA and IRQ requests are now queued and will run to completion on their own
without help from the device code (just call request_DMA and when it returns the DMA transfer is complete.) Fixed request_DMA to chunk DMA transfers larger than 1024 bytes to avoid overrunning the mailbox's shared memory. Fixed concurrency issues with DMA requests -- a race condition could cause DMA request data to get clobbered. RT-11 now boots, MSCP behavior is now very reliable.
This commit is contained in:
@@ -88,6 +88,8 @@ rk11_c::rk11_c() :
|
||||
RKDB_reg->reset_value = 0;
|
||||
RKDB_reg->writable_bits = 0x0000; // read only
|
||||
|
||||
_rkda_drive = 0;
|
||||
|
||||
//
|
||||
// Drive configuration: up to eight drives.
|
||||
//
|
||||
@@ -127,8 +129,7 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
{
|
||||
// Write FROM buffer TO unibus memory, IBA on:
|
||||
// We only need to write the last word in the buffer to memory.
|
||||
unibusadapter->request_DMA(
|
||||
this,
|
||||
request.timeout = !unibusadapter->request_DMA(
|
||||
UNIBUS_CONTROL_DATO,
|
||||
request.address,
|
||||
request.buffer + request.count - 1,
|
||||
@@ -139,8 +140,7 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
// Read FROM unibus memory TO buffer, IBA on:
|
||||
// We read a single word from the unibus and fill the
|
||||
// entire buffer with this value.
|
||||
unibusadapter->request_DMA(
|
||||
this,
|
||||
request.timeout = !unibusadapter->request_DMA(
|
||||
UNIBUS_CONTROL_DATI,
|
||||
request.address,
|
||||
request.buffer,
|
||||
@@ -153,8 +153,7 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
if (request.write)
|
||||
{
|
||||
// Write FROM buffer TO unibus memory
|
||||
unibusadapter->request_DMA(
|
||||
this,
|
||||
request.timeout = !unibusadapter->request_DMA(
|
||||
UNIBUS_CONTROL_DATO,
|
||||
request.address,
|
||||
request.buffer,
|
||||
@@ -163,8 +162,7 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
else
|
||||
{
|
||||
// Read FROM unibus memory TO buffer
|
||||
unibusadapter->request_DMA(
|
||||
this,
|
||||
request.timeout = !unibusadapter->request_DMA(
|
||||
UNIBUS_CONTROL_DATI,
|
||||
request.address,
|
||||
request.buffer,
|
||||
@@ -172,20 +170,6 @@ void rk11_c::dma_transfer(DMARequest &request)
|
||||
}
|
||||
}
|
||||
|
||||
// And wait for completion.
|
||||
while(true)
|
||||
{
|
||||
timeout.wait_us(50); // Stolen from RL11
|
||||
uint32_t last_address = 0;
|
||||
if (unibusadapter->complete_DMA(
|
||||
this,
|
||||
&last_address,
|
||||
&request.timeout))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If an IBA DMA read from memory, we need to fill the request buffer
|
||||
// with the single word returned from memory by the DMA operation.
|
||||
if (request.iba && !request.write)
|
||||
|
||||
Reference in New Issue
Block a user