Author Topic: TMS570 exception  (Read 3644 times)

0 Members and 1 Guest are viewing this topic.

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3733
  • Country: nl
Re: TMS570 exception
« Reply #25 on: July 13, 2022, 04:34:07 pm »
Yes saving the current cpsr into spsr_undef is not the way to do it. On exception or interrupt the cpsr is automatically stored to spsr in the bank belonging to the exception or interrupt. Then the cpu sets the needed register bank in the cpsr.

This means that when you do this saving again in the exception handler you will overwrite the cpsr data from before the exception.

Code: [Select]
  //Check interrupt on enabled and active
  if((core->status->flags.I == 0) && (core->irq == 1))
  {
    //Handle the interrupt
    //Load exception r14 with current pc plus 4. The manual states for entering and returning from interrupt sub r14, r14, #4; stmfd sp!, {r14}; ...; ldmfd sp!, {pc}^
    *core->registers[ARM_REG_BANK_IRQ][14] = *core->program_counter + 4;
   
    //Load exception spsr with current psr
    *core->registers[ARM_REG_BANK_IRQ][ARM_REG_SPSR_IDX] = core->status->word;
     
    //Switch to irq exception mode
    core->status->flags.M = ARM_MODE_IRQ;
   
    //Return to arm execution state
    core->status->flags.T = 0;
    core->status->flags.J = 0;
   
    //Disable interrupts
    core->status->flags.I = 1;
   
    //Clear the interrupt flag to signal it has been handled
    core->irq = 0;
   
    //Load endianness from cp15 (not implemented here since it is not used in the scope)
   
    //Switch the current bank to the irq bank
    core->current_bank = ARM_REG_BANK_IRQ;
   
    //Set the internal mode to irq mode
    core->current_mode = ARM_MODE_IRQ;
   
    //Load pc with the irq vector address. Depending om cp15 it could also be 0xFFFF0018, but not implemented here.
    *core->program_counter = 0x00000018;
  }

This piece of code is the irq handling in my emulator. For the undefined instruction exception the actions are similar, but with a different register bank.

You can see that R14 of the IRQ register bank is loaded with the current program counter + 4. Then the SPSR of the IRQ register bank is loaded with the current CPSR.
Then the flags in the CPSR are set to what they need to be. The last thing done is to load the PC with the IRQ vector address.

I wrote this emulator for the reverse engineering of the FNIRSI-1013D so left out things that I knew not being used. But writing it did teach me how the cpu works to some extend.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #26 on: July 13, 2022, 06:29:10 pm »
“ Yes saving the current cpsr into spsr_undef is not the way to do it. On exception or interrupt the cpsr is automatically stored to spsr in the bank belonging to the exception or interrupt. Then the cpu sets the needed register bank in the cpsr. “

Yes, but this, if I'm not mistaken, only happens if the processor provides an exception for a certain event. In fact, what you say happens to me when I generate a given abortion for example. But here the situation is different because for the division by zero the processor of the TMS570 does not provide for the activation of any exception in fact, as I said in previous posts, in the asm files that manage the divisions it is explicitly reported that the division by zero simply returns zero. Then always in these files there is a note in which if you want to activate an exception, instead of returning zero, you have to edit the file. I made these changes and they would be what I told you in the previous post and they are as follows. So when I make these changes I’m not yet in a handler but I’m still within the split function. What I do is this:

When divider by zero raises i want to generate an undef exception so i have to save actual cpsr to spsr_undef and actual PC to R14_undef.
To do this i have to:

Inside division function
- save PC
- switch to undef mode
- save cpsr to spsr_undef
- save pc to R14 undef
- mov pc, #addr_undef_exception

AFTER inside isr i restore the System.

This behaviour works good when inside main i Write directly a/b, i able to restore the System and go to nextfunc():

Int main()
{
Uint32 a=1;
Uint32 b=0;
Uint32 c=0;

C=a/b;<———

Nextfunc();
}

My problem is Only when my divison is inside a nested function.
 

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3733
  • Country: nl
Re: TMS570 exception
« Reply #27 on: July 13, 2022, 07:24:24 pm »
It is getting a bit fuzzy.

What are you using to do the coding and debugging?

You are talking about inside the division function, but before you mentioned the specific arm instructions UDIV and SDIV. These are not functions you can add code to, so what is it that you are doing. Keep in mind I don't know anything about the TMS570. Everything I wrote here is general ARM knowledge.

The thing you have to remember is that the program counter (R15) does not point to the next instruction, but multiple bytes further in memory. Not sure if it is 4 or 8. And it also depends on the state the cpu is in. ARM or THUMB. So copying it to R14 and then returning from exception with the intended instructions might not be correct. See the comment line in the code bit I posted. (5th line in the code section) Try to find information about this in the programmers manual.

To me it feels you are doing things that are not normal usage of the cpu.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #28 on: July 13, 2022, 08:17:34 pm »
Before i mentioned udiv sdiv, but AFTER i see, in the division file .asm , that TI use udiv and SDIV only when we are not in the case of divided by zero.

Yes the return pc has an offset depending on exception.

Today i also tried to use udiv also in case divided by zero and if i select DZ bit, that i mentioned in previous post, the exception raises automatically.
 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #29 on: July 13, 2022, 08:18:34 pm »
Before i mentioned udiv sdiv, but AFTER i see, in the division file .asm , that TI use udiv and SDIV only when we are not in the case of divided by zero.

Yes the return pc has an offset depending on exception.

Today i also tried to use udiv also in case divided by zero and if i select DZ bit, that i mentioned in previous post, the exception raises automatically.

Today i’ll show you this code.

 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #30 on: July 14, 2022, 06:39:58 am »
Good morning

file udiv_32.asm and div0.asm.
As you can see TI use UDIV only whene we are not in the case of divided by zero operation.

At line 209 the system goes to that function that is located in the second file attached divide by zero. In div_0.asm, as you can see, there is nothing. And in their head there is written:

"The functions can be overridden to implement system specific implementations like returning a fixed value or raising an exception"

The are also two files in wich there are my lines added.

Thank you
« Last Edit: July 14, 2022, 07:21:24 am by lorenrus »
 

Online pcprogrammer

  • Super Contributor
  • ***
  • Posts: 3733
  • Country: nl
Re: TMS570 exception
« Reply #31 on: July 14, 2022, 08:12:55 am »
Sorry, but that is to deep into things.

Even if it is study, I don't see the gain in figuring this out. It is not normal usage of a cpu.

If you need some information about the division being by zero it is much easier to just check the input parameter before calling the division operation and call an assert function to take action on it. Not try to do something out of the ordinary where things don't work as expected because you don't know the full ins and outs of the processor.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf