Author Topic: TMS570 exception  (Read 4315 times)

0 Members and 1 Guest are viewing this topic.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
TMS570 exception
« on: July 09, 2022, 10:03:49 am »
Hi

i'm using TMS570 and i'm managing how to return from exception. I saw the documentation of arm cortex r5 and tms570.

Firt question:

i have these exceptions:

1) undef instr
2) data abort
3) abort prefetch
4) sw int

i able to simulate exceptions 2) and 3), but not the others. Can you help me how can i do this ?

Second question:

In the doc i see that to recover the system from exception i ha to save the last PC value from the specific reg of the exception.
Infact for "Data abort" i did this without problem.

For "ABORT PREFETCH" i follow the same steps but i don't be able to recover the value of PC.

In particular in the same point of DATA ABORT ,in which i save the value of PC, for the ABORT PREFETCH i have a value of PC equal to entry point.

in the docs the steps are the same for all of exceptions.

Can ypu help me ?

Thank you
 

Offline rsjsouza

  • Super Contributor
  • ***
  • Posts: 6070
  • Country: us
  • Eternally curious
    • Vbe - vídeo blog eletrônico
Re: TMS570 exception
« Reply #1 on: July 09, 2022, 11:12:05 am »
For 1) above, if the code branches to a data section you can get this to be triggered. The details escape me but, if you are using C, you can try to force using inline assembly to LDR a data address to the PC.

I assume you already know the app note below, right? If not, it might give you some ideas:

Interrupt and Exception Handling on Hercules™ ARM® Cortex®-R4/5-Based Microcontrollers
Vbe - vídeo blog eletrônico http://videos.vbeletronico.com

Oh, the "whys" of the datasheets... The information is there not to be an axiomatic truth, but instead each speck of data must be slowly inhaled while carefully performing a deep search inside oneself to find the true metaphysical sense...
 
The following users thanked this post: lorenrus

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #2 on: July 09, 2022, 11:24:44 am »
To trigger the sw int (number 4 on your list) you have to use the software interrupt assembler instruction. (swi)

Go to the ARM developer sight for more info: https://developer.arm.com/documentation/ddi0460/d/I43209

To trigger the undef instr (number 1 on your list) you have to make up a 32 bit code, that is not recognized as an instruction.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #3 on: July 09, 2022, 11:31:56 am »
Hi

i'm using Assembler C to save PC value.

i'm reading the doc.

"The processor takes the undefined instruction exception when it encounters an instruction that is undefined in the appropriate version of the ARM instruction set, or which is for the VFP when the VFP is
disabled
. The undefined instruction exception can be used to emulate undefined instructions, or simply to handle fault situations"

i don't understand the meaning of bold expression.

Thank you very much
 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #4 on: July 09, 2022, 11:34:20 am »
To trigger the sw int (number 4 on your list) you have to use the software interrupt assembler instruction. (swi)

Go to the ARM developer sight for more info: https://developer.arm.com/documentation/ddi0460/d/I43209

To trigger the undef instr (number 1 on your list) you have to make up a 32 bit code, that is not recognized as an instruction.

hi and thank you.

ok now i see the link.

Can you explain me what do you mean with "you have to make up a 32 bit code" ?

thank you.


 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #5 on: July 09, 2022, 11:47:03 am »
When you look at how the ARM instruction set is coded in binary, you can see that there are specific fields, like the conditional execution bits, etc. Within the 32 bits available there are combinations that do not decode into a valid instruction for the processor. It is these codes that trigger the undefined instruction interrupt.

For the cortex R5 it depends on which ARM version it is based on which instructions are valid. Be it v5, v6, v7, etc. That is what they mean with the first bold section of what you wrote. The second bit points to the Vector Floating Point processor that can be present and then take instructions specific for this processor. If it is disabled these specific instructions also trigger the undefined instruction interrupt.

This makes it possible to handle these instructions in software.

So what I meant with the make up a 32 bit code, is that you have to find a code that is not mapped to a known instruction and then embed it in your code. When the instruction fetch system reads this unknown code it triggers the undefined instruction interrupt.

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4534
  • Country: nz
Re: TMS570 exception
« Reply #6 on: July 09, 2022, 12:01:13 pm »
To trigger the sw int (number 4 on your list) you have to use the software interrupt assembler instruction. (swi)

Go to the ARM developer sight for more info: https://developer.arm.com/documentation/ddi0460/d/I43209

To trigger the undef instr (number 1 on your list) you have to make up a 32 bit code, that is not recognized as an instruction.

hi and thank you.

ok now i see the link.

Can you explain me what do you mean with "you have to make up a 32 bit code" ?

thank you.

Are you running in ARM mode, or in Thumb2 mode?

In, for example, ARM mode all instructions are 32 bits in size. There are 2^32 = 4294967296 possible instructions, but not all have been defined.  The manual (Cortex-R5F, ARMv7-R) lists the opcodes that are defined. All other opcodes are undefined.

One easy way to find one would be to look for a new instruction defined by ARMv8-R, and try to use it.
 
The following users thanked this post: lorenrus

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #7 on: July 09, 2022, 02:01:24 pm »
okok, clear.

i'm reading R5 RM.

for undef instruction for example i could do "divide by zero" with UDIV or SDIV instructions.

- i have to set DZ bit of SCTLR equals to 1 to generate a fault undef instr by the processor, right ? Because if DZ is equal to zero the result of divide by zero operation is equal to zero, right ?
 
after i see this:

Code: [Select]
addr = R14_undef - 2
instr = Memory[addr,2]
if (instr >> 11) > 28 { /* 32-bit instruction */
instr = (instr << 16) | [b]Memory[/b][addr+2,2]
if ([b]emulating, so return after instruction wanted[/b]) }
R14_undef += 2 //
} //
}

After this, instr holds the instruction (in the range 0x0000-0xE7FF for a 16-bit instruction,
0xE8000000-0xFFFFFFFF for a 32-bit instruction), and the exception can be returned from
using a MOVS PC, R14 to return after it.


For R14_undef i think that i can write an assembler function that returns this value, but what would the Memory variable be if I wanted to represent it in C ? It would appear to be a matrix.
Which is the meaning of emulating, so return after instruction wanted ?


in my debug configuration i see that is set Mixed ARM thumb, but i think that i'll read the thumb bit in the Program Status Register.


Also i see this:

There are special cases for reading R15:
• reading the address of the current instruction plus, either:
— 4 in Thumb state
— 8 in ARM state.
• reading 0x00000000 (zero). --> this is the case that i found when i try to recover the system for prefetch abort ?

Thank you


 
 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #8 on: July 09, 2022, 02:15:15 pm »
To trigger the sw int (number 4 on your list) you have to use the software interrupt assembler instruction. (swi)

Go to the ARM developer sight for more info: https://developer.arm.com/documentation/ddi0460/d/I43209

To trigger the undef instr (number 1 on your list) you have to make up a 32 bit code, that is not recognized as an instruction.

hi and thank you.

ok now i see the link.

Can you explain me what do you mean with "you have to make up a 32 bit code" ?

thank you.

Are you running in ARM mode, or in Thumb2 mode?

In, for example, ARM mode all instructions are 32 bits in size. There are 2^32 = 4294967296 possible instructions, but not all have been defined.  The manual (Cortex-R5F, ARMv7-R) lists the opcodes that are defined. All other opcodes are undefined.

One easy way to find one would be to look for a new instruction defined by ARMv8-R, and try to use it.


Ok

can i use this expressione to generate the undef instr described in attached file ?

MCR p15, #0, Rt, c7, c0, #0

Thank you
« Last Edit: July 09, 2022, 02:18:51 pm by lorenrus »
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #9 on: July 09, 2022, 03:48:03 pm »
Ok

can i use this expressione to generate the undef instr described in attached file ?

MCR p15, #0, Rt, c7, c0, #0

Thank you

I don't think so. The MCR instruction is a valid instruction and addressing the control co-processor with it is normal use. Sending the wrong data to the control co-processor might result in undetermined behavior. But I might be wrong.

Why are you so focused on these exceptions?

When doing basic bare metal work on an ARM CPU these exceptions will most likely never happen. And when you are using a RTOS it will handle them and you don't need to write code for it.

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #10 on: July 09, 2022, 04:05:56 pm »
okok, clear.

i'm reading R5 RM.

for undef instruction for example i could do "divide by zero" with UDIV or SDIV instructions.

- i have to set DZ bit of SCTLR equals to 1 to generate a fault undef instr by the processor, right ? Because if DZ is equal to zero the result of divide by zero operation is equal to zero, right ?
 
after i see this:

Code: [Select]
addr = R14_undef - 2
instr = Memory[addr,2]
if (instr >> 11) > 28 { /* 32-bit instruction */
instr = (instr << 16) | [b]Memory[/b][addr+2,2]
if ([b]emulating, so return after instruction wanted[/b]) }
R14_undef += 2 //
} //
}

After this, instr holds the instruction (in the range 0x0000-0xE7FF for a 16-bit instruction,
0xE8000000-0xFFFFFFFF for a 32-bit instruction), and the exception can be returned from
using a MOVS PC, R14 to return after it.


For R14_undef i think that i can write an assembler function that returns this value, but what would the Memory variable be if I wanted to represent it in C ? It would appear to be a matrix.
Which is the meaning of emulating, so return after instruction wanted ?


in my debug configuration i see that is set Mixed ARM thumb, but i think that i'll read the thumb bit in the Program Status Register.


Also i see this:

There are special cases for reading R15:
• reading the address of the current instruction plus, either:
— 4 in Thumb state
— 8 in ARM state.
• reading 0x00000000 (zero). --> this is the case that i found when i try to recover the system for prefetch abort ?

Thank you

I don't know about the divide by zero causing an undefined instruction interrupt.

The bit about the 32 bits instruction range being 0xE8000000 - 0xFFFFFFFF feels wrong. The top 4 bits are the condition field bits, and can be different from 0xE.

The pseudo code you posted shows how to determine if the data read from before the return instruction (the data that caused the interrupt) is a 32 bit ARM instruction or a 16 bit THUMB(2) instruction. The "if" part is where you put your own code to handle "emulate" the undefined instruction.

Did not know that trick of shifting and checking against being > 28.

The Memory bit used in the pseudo code is just a referral to the system memory, which in some way is a big array of bytes.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #11 on: July 09, 2022, 05:23:27 pm »
I have to realize a doc with all exceptions, describe in the first post, and analyze their behaviour, simulate them and understand how to recover the system.

Do you think that is possible to recover the system from all exceptions ?

Thank you
 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #12 on: July 09, 2022, 05:27:51 pm »
okok, clear.

i'm reading R5 RM.

for undef instruction for example i could do "divide by zero" with UDIV or SDIV instructions.

- i have to set DZ bit of SCTLR equals to 1 to generate a fault undef instr by the processor, right ? Because if DZ is equal to zero the result of divide by zero operation is equal to zero, right ?
 
after i see this:

Code: [Select]
addr = R14_undef - 2
instr = Memory[addr,2]
if (instr >> 11) > 28 { /* 32-bit instruction */
instr = (instr << 16) | [b]Memory[/b][addr+2,2]
if ([b]emulating, so return after instruction wanted[/b]) }
R14_undef += 2 //
} //
}

After this, instr holds the instruction (in the range 0x0000-0xE7FF for a 16-bit instruction,
0xE8000000-0xFFFFFFFF for a 32-bit instruction), and the exception can be returned from
using a MOVS PC, R14 to return after it.


For R14_undef i think that i can write an assembler function that returns this value, but what would the Memory variable be if I wanted to represent it in C ? It would appear to be a matrix.
Which is the meaning of emulating, so return after instruction wanted ?


in my debug configuration i see that is set Mixed ARM thumb, but i think that i'll read the thumb bit in the Program Status Register.


Also i see this:

There are special cases for reading R15:
• reading the address of the current instruction plus, either:
— 4 in Thumb state
— 8 in ARM state.
• reading 0x00000000 (zero). --> this is the case that i found when i try to recover the system for prefetch abort ?

Thank you

I don't know about the divide by zero causing an undefined instruction interrupt.


In R5 RM:

"Undefined Instruction exceptions also occur when a UDIV or SDIV instruction is executed, the value in Rm is zero, and the DZ bit in the SCTLR is set."

In the ARMv7-R profile, the SCTLR.DZ bit enables divide by zero fault detection:

SCTLR.DZ == 0
Divide-by-zero returns a zero result.

SCTLR.DZ == 1
SDIV and UDIV generate an Undefined Instruction exception on a divide-by-zero.

The SCTLR.DZ bit is cleared to zero on reset.
 
The following users thanked this post: pcprogrammer

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #13 on: July 09, 2022, 05:35:25 pm »
To some extend yes a system can recover from all exceptions as long as it is not a hardware failure.

In case of a glitch in the memory the processor might encounter an undefined instruction interrupt (exception) and the software could recover from this by resetting and reloading the code. If on the other hand a bit in memory is corrupt on a hardware level, resetting and reloading won't help.

So it all depends on how the system is setup to handle these exceptions.

Quite often these exceptions are implemented with just an endless loop, causing a system to hang when such an exception occurs. Then a hard reset is needed. (Power down and up again, or press an actual reset button)

This because in normal operation these exceptions won't occur.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #14 on: July 09, 2022, 06:35:14 pm »
Ok

how i said in my first post for now i able to recover only from DATA ABORT and simulate only DATA ABORT and PREFETCH ABORT.

I reported that in PREFETCH ABORT when i try to read PC value i see that it' s value is zero instead in DATA ABORT i have the correct value of next instruction.

This behaviour is correct ?

Do you know how can i recover and simulate the other exceptions ?

Thank you
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #15 on: July 09, 2022, 07:23:09 pm »
I have not looked at the exceptions in depth, but think the prefetch abort can only be recovered with a reset. Probably the reason why R14 holds zero as a return address.

Recovering from exceptions depends on what you want the system to do. If it is ok to just fall into an endless loop than that is perfect "recovery" from the exception.

Using a watchdog timer can also be a recovery mechanism. It will reset the system on a time out.

Study the guide about the ARM CPU further and you will find the answers about the exceptions.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #16 on: July 11, 2022, 12:05:01 pm »
I able to generate an undef istr with:

asm(“ .word 0xFFFFFFFF”);

But i don’t understand why?

What does this Line of code do ?
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #17 on: July 11, 2022, 12:56:26 pm »
Here is a page from an older ARM architecture reference manual.



It shows how the instructions are coded. You can see that the top 4 bits form the condition field. When you look at the last row you see "Unconditional instructions" and a referral to Figure A3-6, which is shown below.



When you look again at the last line you can see that all instructions with 0xFF in the top 8 bits are undefined. So every word ranging from 0xFF000000 to 0xFFFFFFFF is going to trigger the undefined instruction. This applies to the ARM versions this document is written for. (Up to ARMv6)

Edit: Increased the font size to make it more clear
« Last Edit: July 11, 2022, 12:59:08 pm by pcprogrammer »
 

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #18 on: July 11, 2022, 01:17:14 pm »
Oh yes this part is clear. I mean the assembler line .word followed by value, in this case 0xFFFFFFFF, what does it do? Is like a pointer to the value 0xFFFFFFFF?

Thank you
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #19 on: July 11, 2022, 01:42:25 pm »
Ok, guess I did not read your post properly.

What that line does is add 0xFFFFFFFF into the code stream.

When you write in assembler there are the instructions like ADD, LDR, etc. These are translated by the assembler to binary codes. But there are also directives like .word that allow you to put constants into the code stream.

Here is a screenshot of output from Ghidra, which is a disassembler. In assembler the first two columns are not filled. In the first column you would put labels that you can use to jump to. The third shows the opcode, and the fourth the operand. Here they use the directive ddw to insert a 32 bit value instead of .word. It just depends on the assembler which directives can be used.

In C you use the "asm ();" directive to insert assembler instructions or directives.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #20 on: July 11, 2022, 08:43:05 pm »
okok clear thank you very much.

today i able to generate undef and recover the system through the PC value saved in R14 related to the exceptions.

I tried again to recover from abort prefetch but i think that is not possible, because:

i can cause abort prefetch exception jumping in unmapped address or reserved  address, if i say jump it means that i have to modify the current PC value. With this considerations i think that shoudn't be possibile ? What do you think ?

Tomorrow i have to study SW int exception. Do you have any idea ?


For divide by zero exception:

in R5 Ref Man is reported that is possible to generate this but today i was reading as functions of TI lib and i see that by default TI set: "DIVIDED BY ZERO RETURN ZERO".
But is possible to modify this how is written in the head of the asm file.
If i would like to modify, how can i say in assembler that i want to generate an exception ?
I also did a test, knowing it couldn't be done like this, by doing:

modified section (pseudo cod):

Code: [Select]
#define UNDEF_EXCETION_ADDR 0x00000004

uint32 PC;

if (divide_by_zero)
PC = ((uint32*)UNDEF_EXCETION_ADDR);

all pseudo cod done in assembler.

But as I expected the jump to that instruction was there but no real exception was thrown.
At this point I wonder how to tell him to activate the exception in assembler.

Thank you very much
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #21 on: July 12, 2022, 05:15:20 am »
Quote
I tried again to recover from abort prefetch but i think that is not possible, because:

i can cause abort prefetch exception jumping in unmapped address or reserved  address, if i say jump it means that i have to modify the current PC value. With this considerations i think that shoudn't be possibile ? What do you think ?

I have not read up on prefetch abort exception, but you basically answered your own question. When the processor tries to fetch an instruction from non existing memory, the change that the data on the next location would be valid is practically none. So it makes no sense to jump back to that location.

The only option to recover would then be to reset the system.

Quote
Tomorrow i have to study SW int exception. Do you have any idea ?

The software interrupt exception is mostly used for task switching in an RTOS. In C there is the "sleep" function. In a multi tasking environment this could use the software interrupt (SWI instruction) to return control to the OS. This way the system is able to change the privilege level from "user" back to "system" when I'm not mistaken. Do not have much experience with this.

Quote
For divide by zero exception

I'm not familiar with the TMS570 and the libraries that come with it, so you are on your own there.

Quote
But as I expected the jump to that instruction was there but no real exception was thrown.
At this point I wonder how to tell him to activate the exception in assembler.

Jumping to an exception handler is indeed not the same as when the exception is actually triggered. You already looked into the divide by zero yourself.
The "SCTLR.DZ" has to be set to enable the undefined instruction exception when a divide by zero is detected by the processor. (Have not looked at the documentation if this is true)

So to get it working you have to set this bit before using the divide instructions.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #22 on: July 13, 2022, 01:47:00 pm »
I have a news for divider by zero.
For others exceptions is all ok.

I see in the code of TI lib that by default return 0.
But if you want you can edit this file.

I try to do in the main: c=1/0.

I edit this file and i modify the cpsr for undef i salve the cpsr to spsr_undef i save the last value of PC. And i able to restore the system.

But there is a problem beacause if i have a div operation in a nested function how can i have the correct value of pc?

Example:

Void func1()
{
     Func2();
}

Void func2()
{
     1/0;
}


Main()
{

Func1();

Func3();

}

So the the pc that is important for me is generate from func1 in the LR reg. but when i switch to func2 i loose the correct pc.

How can i do this ?

Thank you
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 4396
  • Country: nl
Re: TMS570 exception
« Reply #23 on: July 13, 2022, 02:23:36 pm »
Well for that the arn cpu has register banks, and there is the use of stack.

ARM does not have what other cpu's might have and that is a direct copying to stack of the instruction pointer. Instead when a sub routine is called the return address is loaded into R14. To allow for interrupts to still be possible they incorporated the register banks. In the case of an interrupt or exception the cpu first switches to the bank related to the interrupt or exception. Then it loads the return address into that banks R14, leaving R14 in the other bank in tact.

So at the end of the interrupt or exception, the PC can be loaded from R14, which causes it to return to the instruction right after where it left of. In the process the cpu also switches back to the register bank that was set before the interrupt or exception. In this bank R14 holds the address just after the call of the sub routine. The ARM developer manuals contain information about this. Search for "return from interrupt" or "return from exception".

My recollection of the workings is a bit vague. I wrote an emulator for armv5 last year where I handled this stuff, but when working with C the compiler takes care of all these things and I forgot the actual inner workings. (The code can be found here: https://github.com/pecostm32/FNIRSI-1013D-1014D-Hack/tree/main/Test%20code/Scope_emulator)

But back to your example, there the exception will occur in "func2" and your handler should return to the point right after the divide instruction. The code will then continue and return to "func1" and then back to "Main"

In the code generated by the compiler there will be bits that copy the address in R14 onto the stack to allow for nested sub routines.

Offline lorenrusTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: it
Re: TMS570 exception
« Reply #24 on: July 13, 2022, 03:59:19 pm »
Yes i do extactly what are you saying.

I found the problem, but i don’t know where is my error.

I able to resume correctly from exception infact the return address is the addr of brackets immediately following func2().

Func1()
{
   Func2();
} <———————here !!!!! I put here a break poi t. Here i see the disassembly and i see that will be execute pop {r1, r2, r3, pc} . This is necessary to restore the address of previous nested function.

I go on step by step i see the fail because the System gode to entry func at addr 0x00000000 and pop {r1, r2, r3, pc} fails. But is caused by the operation that i added.

In particoular i change mode from System to undef, so i work on cpsr. I save cpsr in spsr_undef.
These operations could generate it ?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf