Re: [PATCH 4/4] sim/mips: Recognise a software interrupt request

Sebastian Huber <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
----- Am 18. Aug 2026 um 12:42 schrieb Andrew Burgess [email protected]:

> Sebastian Huber <[email protected]> writes:
> 
>> Add support for the Cause.IP0 and Cause.IP1 software generated
>> interrupts defined by the MIPS Architecture For Programmers Volume III:
>> The MIPS Privileged Resource Architecture.
>>
>> Deliver it from the event queue rather than in place, because
>> signal_exception() leaves the handler address in the program counter for
>> an interrupt and the instruction being executed would overwrite it.
>>
>> Signed-off-by: Sebastian Huber <[email protected]>
>> ---
>>  sim/mips/interp.c   | 64 +++++++++++++++++++++++++++++++++++++++++++--
>>  sim/mips/sim-main.h |  2 ++
>>  2 files changed, 64 insertions(+), 2 deletions(-)
>>
>> diff --git a/sim/mips/interp.c b/sim/mips/interp.c
>> index 5dbd1482b99..fddb96d00ed 100644
>> --- a/sim/mips/interp.c
>> +++ b/sim/mips/interp.c
>> @@ -295,6 +295,58 @@ static const OPTION mips_options[] =
>>  
>>  int interrupt_pending;
>>  
>> +/* An interrupt is requested while the interrupts are enabled and a pending
>> +   bit of the Cause register meets its mask bit in the Status register:
>> +
>> +     Status.IE = 1, Status.EXL = 0, Status.ERL = 0, Cause.IP & Status.IM != 0
>> +
>> +   MIPS Architecture For Programmers Volume III: The MIPS Privileged Resource
>> +   Architecture, the Interrupts chapter.  The R3000 generation, which the
>> +   R3900 belongs to, has no exception level and disables the interrupts by
>> +   shifting the interrupt enable stack of its Status register instead, so only
>> +   the current enable takes part; see the IDT R30xx Family Software Reference
>> +   Manual, the Status register of the CPU control chapter.  */
>> +static int
>> +interrupt_requested (sim_cpu *cpu)
>> +{
>> +  if ((SR & status_IE) == 0)
>> +    return 0;
>> +
>> +#ifndef SUBTARGET_R3900
>> +  if ((SR & (status_EXL | status_ERL)) != 0)
>> +    return 0;
>> +#endif
>> +
>> +  /* Only the software interrupts.  A hardware interrupt keeps its pending bit
>> +     set until its device is served. The device model delivers it.  */
> 
> Two spaces after 'served.' please.
> 
>> +  return ((CAUSE >> cause_IPSW_shift) & (SR >> status_IM_shift)
>> +	  & cause_IPSW_mask) != 0;
>> +}
>> +
>> +static void
>> +software_interrupt_event (SIM_DESC sd, void *data)
>> +{
>> +  sim_cpu *cpu = STATE_CPU (sd, 0);
>> +  address_word cia = CPU_PC_GET (cpu);
>> +
>> +  /* Recheck, because the write which scheduled this may have been undone in
>> +     the meantime.  */
>> +  if (interrupt_requested (cpu))
>> +    SignalExceptionInterrupt (0);
>> +}
>> +
>> +/* Deliver a pending interrupt at the next instruction boundary.  It cannot be
>> +   delivered here: signal_exception() leaves the handler address in the program
>> +   counter for an interrupt and the instruction which is being executed would
>> +   overwrite it.  This is why the hardware interrupts arrive through the event
>> +   queue as well.  */
>> +static void
>> +check_interrupts (SIM_DESC sd, sim_cpu *cpu)
>> +{
>> +  if (interrupt_requested (cpu))
>> +    sim_events_schedule (sd, 1, software_interrupt_event, NULL);
>> +}
>> +
>>  void
>>  interrupt_event (SIM_DESC sd, void *data)
>>  {
>> @@ -2269,14 +2321,20 @@ decode_coproc (SIM_DESC sd,
>>  		if (op == cp0_mfc0 || op == cp0_dmfc0)
>>  		  GPR[rt] = SR;
>>  		else
>> -		  SR = GPR[rt];
>> +		  {
>> +		    SR = GPR[rt];
>> +		    check_interrupts (sd, cpu);
>> +		  }
>>  		break;
>>  		/* 13 = Cause              R4000   VR4100  VR4300 */
>>  	      case 13:
>>  		if (op == cp0_mfc0 || op == cp0_dmfc0)
>>  		  GPR[rt] = CAUSE;
>>  		else
>> -		  CAUSE = GPR[rt];
>> +		  {
>> +		    CAUSE = GPR[rt];
>> +		    check_interrupts (sd, cpu);
>> +		  }
>>  		break;
>>  		/* 14 = EPC                R4000   VR4100  VR4300 */
>>  	      case 14:
>> @@ -2391,6 +2449,7 @@ decode_coproc (SIM_DESC sd,
>>  	      {
>>  		PC = EPC;
>>  		SR &= ~status_EXL;
>> +		check_interrupts (sd, cpu);
>>  	      }
> 
> This is the ERET case for handling the situation where the ERL bit is
> cleared.  If I reproduce your patched code, but with more context, we
> see this:
> 
>  /* ERET */
>  if (SR & status_ERL)
>    {
>      /* Oops, not yet available */
>      sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
>      PC = EPC;
>      SR &= ~status_ERL;
>    }
>  else
>    {
>      PC = EPC;
>      SR &= ~status_EXL;
>      check_interrupts (sd, cpu);
>    }
> 
> Now clearly the `if` block is broken, we're setting PC from the wrong
> place I think.  But if this block _was_ ever fixed then we're going to
> need a check_interrupts call on that path too, right?
> 
> My suggestion is that we move the check_interrupts call after the `else`
> block, like this:
> 
>  /* ERET */
>  if (SR & status_ERL)
>    {
>      /* Oops, not yet available */
>      sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
>      PC = EPC;
>      SR &= ~status_ERL;
>    }
>  else
>    {
>      PC = EPC;
>      SR &= ~status_EXL;
>    }
>  check_interrupts (sd, cpu);
> 
> This doesn't fix the `if` block, but if someone ever does fix that path,
> then the check_interrupts call will be in place ready for them.
> 
> What do you think?

Thanks for your review. I used the RTEMS test suite as my main driver for the changes.

Yes, I think that moving the check after the `if` block makes sense.

> 
> If you're happy to accept the two changes then:
> 
> Approved-By: Andrew Burgess <[email protected]>

I am only an occasional contributor, so I am not sure if I understood it correctly.

1. I remove the Signed-off-by from all four patches.

2. I fix all your review comments.

3. I run my tests again.

4. I add the Approved-By: Andrew Burgess <[email protected]> to all four commits.

5. I don't send a v2 version to the patches list.

6. I check in the updated patch set directly.

Kind regards,
Sebastian

-- 
embedded brains GmbH & Co. KG
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: [email protected]
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.