@@ -154,6 +154,9 @@ void DMAChannel::finish_cmd() {
154154 // get command code
155155 this ->cur_cmd = cmd_desc[3 ] >> 4 ;
156156
157+ // save interrupt bits from the completing command before cmd_ptr may change
158+ uint8_t saved_cmd_bits = cmd_desc[2 ];
159+
157160 // all commands except STOP update cmd.xferStatus and
158161 // perform actions under control of "i" interrupt, "b" branch, and "w" wait bits
159162 if (this ->cur_cmd < DBDMA_Cmd::STOP) {
@@ -206,8 +209,9 @@ void DMAChannel::finish_cmd() {
206209 if (this ->cur_cmd < DBDMA_Cmd::STOP && !branch_taken)
207210 this ->cmd_ptr += 16 ;
208211
212+ // use the interrupt bits saved before cmd_ptr was advanced or branched
209213 if (this ->cur_cmd < DBDMA_Cmd::STOP) {
210- this ->update_irq ();
214+ this ->update_irq (saved_cmd_bits );
211215 }
212216
213217 this ->cmd_in_progress = false ;
@@ -272,19 +276,22 @@ void DMAChannel::xfer_quad(const DMACmd *cmd_desc, DMACmd *cmd_host) {
272276}
273277
274278void DMAChannel::update_irq () {
275- // obtain real pointer to the descriptor of the completed command
279+ // For abort path (called from reg_write when RUN is cleared): cmd_ptr still
280+ // points to the current command, so reading from it is correct here.
276281 MapDmaResult res = mmu_map_dma_mem (this ->cmd_ptr , 16 , false );
277- uint8_t *cmd_desc = res.host_va ;
282+ this ->update_irq (res.host_va [2 ]);
283+ }
278284
285+ void DMAChannel::update_irq (uint8_t cmd_bits) {
279286 // STOP doesn't generate interrupts
280287 if (this ->cur_cmd < DBDMA_Cmd::STOP) {
281288 // react to cmd.i (interrupt) bits
282- if (cmd_desc[ 2 ] & 0x30 ) {
289+ if (cmd_bits & 0x30 ) {
283290 bool cond = true ;
284- if ((cmd_desc[ 2 ] & 0x30 ) != 0x30 ) {
291+ if ((cmd_bits & 0x30 ) != 0x30 ) {
285292 uint16_t int_mask = this ->int_select >> 16 ;
286293 cond = (this ->ch_stat & int_mask) == (this ->int_select & int_mask);
287- if ((cmd_desc[ 2 ] & 0x30 ) == 0x20 ) {
294+ if ((cmd_bits & 0x30 ) == 0x20 ) {
288295 cond = !cond; // generate interrupt if cond = false
289296 }
290297 }
0 commit comments