diff --git a/devices/common/dbdma.cpp b/devices/common/dbdma.cpp index 63077c8876..a99ae788a6 100644 --- a/devices/common/dbdma.cpp +++ b/devices/common/dbdma.cpp @@ -145,6 +145,15 @@ void DMAChannel::interpret_cmd() { } } +void DMAChannel::interpret_until_blocked() { + // Execute ready commands until a transfer is queued or the channel becomes idle/dead. + while (this->is_active()) { + this->interpret_cmd(); + if (this->cmd_in_progress) + break; + } +} + void DMAChannel::update_cmd() { if (this->cur_is_writable) { if (this->cur_cmd < DBDMA_Cmd::STOP) @@ -471,7 +480,7 @@ void DMAChannel::xfer_from_device() { this->get_name().c_str()); } - this->interpret_cmd(); + this->interpret_until_blocked(); } void DMAChannel::xfer_to_device() { @@ -488,7 +497,7 @@ void DMAChannel::xfer_to_device() { this->finish_cmd(); } - this->interpret_cmd(); + this->interpret_until_blocked(); } void DMAChannel::xfer_retry() { @@ -521,9 +530,7 @@ DmaPullResult DMAChannel::pull_data(uint32_t req_len, uint32_t *avail_len, uint8 } // interpret DBDMA program until we get data or become idle - while ((this->ch_stat & CH_STAT_ACTIVE) && !this->queue_len) { - this->interpret_cmd(); - } + this->interpret_until_blocked(); // dequeue data if any if (this->queue_len) { @@ -556,9 +563,7 @@ DmaPushResult DMAChannel::push_data(const char* src_ptr, int len) { } // interpret DBDMA program until we get buffer to fill in or become idle - while ((this->ch_stat & CH_STAT_ACTIVE) && !this->queue_len) { - this->interpret_cmd(); - } + this->interpret_until_blocked(); if (this->queue_len) { len = std::min((int)this->queue_len, len); @@ -570,47 +575,12 @@ DmaPushResult DMAChannel::push_data(const char* src_ptr, int len) { // proceed with the DBDMA program if the buffer became exhausted if (!this->queue_len) { - this->interpret_cmd(); + this->interpret_until_blocked(); } return DmaPushResult::PushedData; } -void DMAChannel::end_pull_data() { - if (!this->is_active()) { - // dead or idle channel? -> no more data - LOG_F(WARNING, "%s: Ending Dead/idle channel -> no more data", - this->get_name().c_str()); - return; - } - - if (this->queue_len) { - this->queue_len = 0; - } else { - this->ch_stat &= ~CH_STAT_FLUSH; - } - - // proceed with the DBDMA program - this->interpret_cmd(); -} - -void DMAChannel::end_push_data() { - if (!this->is_active()) { - LOG_F(WARNING, "%s: Attempt to end push data to dead/idle channel", - this->get_name().c_str()); - return; - } - - if (this->queue_len) { - this->queue_len = 0; - } else { - this->ch_stat &= ~CH_STAT_FLUSH; - } - - // proceed with the DBDMA program - this->interpret_cmd(); -} - bool DMAChannel::is_out_active() { return this->is_active(); } @@ -646,13 +616,7 @@ void DMAChannel::start() { if (this->start_cb) this->start_cb(); - // some DBDMA programs contain commands that don't transfer data - // between a device and memory (LOAD_QUAD, STORE_QUAD, NOP and STOP). - // We thus interprete the DBDMA program until a data transfer between - // a device and memory is queued or the channel becomes idle/dead. - while (!this->cmd_in_progress && this->is_active()) { - this->interpret_cmd(); - } + this->interpret_until_blocked(); } void DMAChannel::resume() { @@ -664,13 +628,7 @@ void DMAChannel::resume() { LOG_F(INFO, "%s: Resuming DMA channel", this->get_name().c_str()); - // some DBDMA programs contain commands that don't transfer data - // between a device and memory (LOAD_QUAD, STORE_QUAD, NOP and STOP). - // We thus interprete the DBDMA program until a data transfer between - // a device and memory is queued or the channel becomes idle/dead. - while (!this->cmd_in_progress && this->is_active()) { - this->interpret_cmd(); - } + this->interpret_until_blocked(); } void DMAChannel::abort() { diff --git a/devices/common/dbdma.h b/devices/common/dbdma.h index 1e48e90c11..f6991f939e 100644 --- a/devices/common/dbdma.h +++ b/devices/common/dbdma.h @@ -125,10 +125,6 @@ class DMAChannel : public DmaBidirChannel, public DmaChannel { bool is_in_active() override; DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len, uint8_t **p_data) override; DmaPushResult push_data(const char* src_ptr, int len) override; - int get_pull_data_remaining() override { return this->queue_len; } - int get_push_data_remaining() override { return this->queue_len; } - void end_pull_data() override; - void end_push_data() override; bool dma_is_ready() override; void xfer_retry() override; @@ -141,6 +137,7 @@ class DMAChannel : public DmaBidirChannel, public DmaChannel { protected: DMACmd* fetch_cmd(uint32_t cmd_addr, DMACmd* p_cmd, bool *is_writable); void interpret_cmd(void); + void interpret_until_blocked(); void update_cmd(); void finish_cmd(); void xfer_quad(bool is_store); diff --git a/devices/common/dmacore.h b/devices/common/dmacore.h index 60695102a7..12c3fca495 100644 --- a/devices/common/dmacore.h +++ b/devices/common/dmacore.h @@ -45,8 +45,6 @@ class DmaOutChannel { virtual bool is_out_active() { return true; } virtual DmaPullResult pull_data(uint32_t req_len, uint32_t *avail_len, uint8_t **p_data) = 0; - virtual int get_pull_data_remaining() { return 1; } - virtual void end_pull_data() {} std::string get_name(void) { return this->name; } @@ -60,8 +58,6 @@ class DmaInChannel { virtual bool is_in_active() { return true; } virtual DmaPushResult push_data(const char* src_ptr, int len) = 0; - virtual int get_push_data_remaining() { return 1; } - virtual void end_push_data() {} std::string get_name(void) { return this->name; }