Discussion:
How to install a trap handler
josef_ahm
2010-10-13 13:58:59 UTC
Permalink
Hi!

I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt = 0x02).

The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal Instruction exception, that allow the processor to jump to the procedure that handles that.

-----

void mytraphandler()
{
int foo;
}

int main(){

unsigned int *trap_entry;

trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN

*trap_entry = ((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22
trap_entry ++;
*trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; // lower 10
trap_entry ++;
*trap_entry = 0x01000000; // nop

sparc_leon23_icache_flush();

asm volatile("ta 2"); //raise the Illegal Insn exception

return 0;

}

-----

While debugging the code, I noticed that the program overwrite successfully the target locations of the trap table, but when the exception is raised ("ta 2"), the control does not jump to the handler procedure.

What am I doing wrong? There's a simpler or smarter way to achieve that?

I'm using gdb connected to the TSIM leon simulator.

Many thanks

Josef



------------------------------------
Jiri Gaisler
2010-10-13 14:01:24 UTC
Permalink
Read the SPARC manual again. "ta 2" generates trap 0x82, not 0x02.
To generate trap 0x02, jump to an address where the instruction is 0.

Jiri.
Post by josef_ahm
Hi!
I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt = 0x02).
The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal
Instruction exception, that allow the processor to jump to the procedure that handles that.
-----
void mytraphandler() { int foo; }
int main(){
unsigned int *trap_entry; trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN *trap_entry =
((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22 trap_entry ++;
*trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; // lower 10
trap_entry ++; *trap_entry = 0x01000000; // nop
sparc_leon23_icache_flush();
asm volatile("ta 2"); //raise the Illegal Insn exception return 0;
}
-----
While debugging the code, I noticed that the program overwrite successfully the target locations
of the trap table, but when the exception is raised ("ta 2"), the control does not jump to the
handler procedure.
What am I doing wrong? There's a simpler or smarter way to achieve that?
I'm using gdb connected to the TSIM leon simulator.
Many thanks
Josef
------------------------------------
Yahoo! Groups Links
------------------------------------
josef_ahm
2010-10-13 15:26:46 UTC
Permalink
Thanks for the explanation, sorry if my questions could seem kind of silly, but I am a real beginner of the Leon environment. :)

Then I substituted the "ta 2" mnemonic with an invalid opcode (0x00400000).

The problem is that my GDB receives a SIGILL signal, which is the result of the translation of the exception detected by the simulator TSIM, instead of continuing the execution jumping to the right entry of the trap table (correct me if I'm wrong).

Is there a way to generate an Illegal Instruction exception while connecting GDB to TSIM, or I have to test it on the real board to make the processor detect the exception?

Josef
Post by Jiri Gaisler
Read the SPARC manual again. "ta 2" generates trap 0x82, not 0x02.
To generate trap 0x02, jump to an address where the instruction is 0.
Jiri.
Post by josef_ahm
Hi!
I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt = 0x02).
The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal
Instruction exception, that allow the processor to jump to the procedure that handles that.
-----
void mytraphandler() { int foo; }
int main(){
unsigned int *trap_entry; trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN *trap_entry =
((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22 trap_entry ++;
*trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; // lower 10
trap_entry ++; *trap_entry = 0x01000000; // nop
sparc_leon23_icache_flush();
asm volatile("ta 2"); //raise the Illegal Insn exception return 0;
}
-----
While debugging the code, I noticed that the program overwrite successfully the target locations
of the trap table, but when the exception is raised ("ta 2"), the control does not jump to the
handler procedure.
What am I doing wrong? There's a simpler or smarter way to achieve that?
I'm using gdb connected to the TSIM leon simulator.
Many thanks
Josef
------------------------------------
Yahoo! Groups Links
------------------------------------
Jiri Gaisler
2010-10-13 15:31:16 UTC
Permalink
Post by josef_ahm
Thanks for the explanation, sorry if my questions could seem kind of silly, but I am a real
beginner of the Leon environment. :)
Then I substituted the "ta 2" mnemonic with an invalid opcode (0x00400000).
The problem is that my GDB receives a SIGILL signal, which is the result of the translation of
the exception detected by the simulator TSIM, instead of continuing the execution jumping to the
right entry of the trap table (correct me if I'm wrong).
Well, that is how gdb is supposed to work. Try to execute an illegal
instruction in a native program under gdb - you *will* stop at this
point as it is a fatal trap.
Post by josef_ahm
Is there a way to generate an Illegal Instruction exception while connecting GDB to TSIM, or I
have to test it on the real board to make the processor detect the exception?
Run your program in TSIM without gdb.

Jiri.
Post by josef_ahm
Josef
Read the SPARC manual again. "ta 2" generates trap 0x82, not 0x02. To generate trap 0x02, jump
to an address where the instruction is 0.
Jiri.
Post by josef_ahm
Hi!
I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt =
0x02).
The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal
Instruction exception, that allow the processor to jump to the procedure that handles that.
-----
void mytraphandler() { int foo; }
int main(){
unsigned int *trap_entry; trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN
*trap_entry = ((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22
trap_entry ++; *trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; //
lower 10 trap_entry ++; *trap_entry = 0x01000000; // nop
sparc_leon23_icache_flush();
asm volatile("ta 2"); //raise the Illegal Insn exception return 0;
}
-----
While debugging the code, I noticed that the program overwrite successfully the target
locations of the trap table, but when the exception is raised ("ta 2"), the control does not
jump to the handler procedure.
What am I doing wrong? There's a simpler or smarter way to achieve that?
I'm using gdb connected to the TSIM leon simulator.
Many thanks
Josef
------------------------------------
Yahoo! Groups Links
------------------------------------
Yahoo! Groups Links
------------------------------------
josef_ahm
2010-10-13 15:42:23 UTC
Permalink
Thank you Jiri, now it works!

Josef
Post by Jiri Gaisler
Post by josef_ahm
Thanks for the explanation, sorry if my questions could seem kind of silly, but I am a real
beginner of the Leon environment. :)
Then I substituted the "ta 2" mnemonic with an invalid opcode (0x00400000).
The problem is that my GDB receives a SIGILL signal, which is the result of the translation of
the exception detected by the simulator TSIM, instead of continuing the execution jumping to the
right entry of the trap table (correct me if I'm wrong).
Well, that is how gdb is supposed to work. Try to execute an illegal
instruction in a native program under gdb - you *will* stop at this
point as it is a fatal trap.
Post by josef_ahm
Is there a way to generate an Illegal Instruction exception while connecting GDB to TSIM, or I
have to test it on the real board to make the processor detect the exception?
Run your program in TSIM without gdb.
Jiri.
Post by josef_ahm
Josef
Read the SPARC manual again. "ta 2" generates trap 0x82, not 0x02. To generate trap 0x02, jump
to an address where the instruction is 0.
Jiri.
Post by josef_ahm
Hi!
I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt =
0x02).
The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal
Instruction exception, that allow the processor to jump to the procedure that handles that.
-----
void mytraphandler() { int foo; }
int main(){
unsigned int *trap_entry; trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN
*trap_entry = ((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22
trap_entry ++; *trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; //
lower 10 trap_entry ++; *trap_entry = 0x01000000; // nop
sparc_leon23_icache_flush();
asm volatile("ta 2"); //raise the Illegal Insn exception return 0;
}
-----
While debugging the code, I noticed that the program overwrite successfully the target
locations of the trap table, but when the exception is raised ("ta 2"), the control does not
jump to the handler procedure.
What am I doing wrong? There's a simpler or smarter way to achieve that?
I'm using gdb connected to the TSIM leon simulator.
Many thanks
Josef
------------------------------------
Yahoo! Groups Links
------------------------------------
Yahoo! Groups Links
------------------------------------
josef_ahm
2010-10-15 08:47:13 UTC
Permalink
Could anyone suggest me the best way to install correctly a trap handler at runtime?

I'd like to develop a C program able to substitute the original Illegal Instruction trap handler with its own handler. To do that, I think the simplest way is to overwrite the 4 instructions relative to the trap table entry of the Illegal Instruction exception, with new instructions that direct the processor to my handler procedure (the classic jmp).

The problem is that the handler procedure must be a leaf procedure, ended by "rett", and I'm wondering if there's a way to implement that procedure in C (the translation of a C function is a normal procedure, surrounded by the save/restore instructions).

Many thanks,

Josef
Post by josef_ahm
Thank you Jiri, now it works!
Josef
Post by Jiri Gaisler
Post by josef_ahm
Thanks for the explanation, sorry if my questions could seem kind of silly, but I am a real
beginner of the Leon environment. :)
Then I substituted the "ta 2" mnemonic with an invalid opcode (0x00400000).
The problem is that my GDB receives a SIGILL signal, which is the result of the translation of
the exception detected by the simulator TSIM, instead of continuing the execution jumping to the
right entry of the trap table (correct me if I'm wrong).
Well, that is how gdb is supposed to work. Try to execute an illegal
instruction in a native program under gdb - you *will* stop at this
point as it is a fatal trap.
Post by josef_ahm
Is there a way to generate an Illegal Instruction exception while connecting GDB to TSIM, or I
have to test it on the real board to make the processor detect the exception?
Run your program in TSIM without gdb.
Jiri.
Post by josef_ahm
Josef
Read the SPARC manual again. "ta 2" generates trap 0x82, not 0x02. To generate trap 0x02, jump
to an address where the instruction is 0.
Jiri.
Post by josef_ahm
Hi!
I would like to add a trap handler at runtime for the "Illegal Instruction" trap (tt =
0x02).
The C code below should write the SPARC opcode on the Leon trap table entry for the Illegal
Instruction exception, that allow the processor to jump to the procedure that handles that.
-----
void mytraphandler() { int foo; }
int main(){
unsigned int *trap_entry; trap_entry = (unsigned int *)0x40000020; //ILLEGAL INSN
*trap_entry = ((((unsigned int)mytraphandler)>>10) &0x3fffff) | 0x29000000; // upper 22
trap_entry ++; *trap_entry = ((((unsigned int)mytraphandler) ) &0x03ff ) | 0x81c52000; //
lower 10 trap_entry ++; *trap_entry = 0x01000000; // nop
sparc_leon23_icache_flush();
asm volatile("ta 2"); //raise the Illegal Insn exception return 0;
}
-----
While debugging the code, I noticed that the program overwrite successfully the target
locations of the trap table, but when the exception is raised ("ta 2"), the control does not
jump to the handler procedure.
What am I doing wrong? There's a simpler or smarter way to achieve that?
I'm using gdb connected to the TSIM leon simulator.
Many thanks
Josef
------------------------------------
Yahoo! Groups Links
------------------------------------
Yahoo! Groups Links
------------------------------------
m.rosenfelder
2010-11-21 15:54:01 UTC
Permalink
Hey there,
Post by josef_ahm
Could anyone suggest me the best way to install correctly a trap handler at runtime?
I'd like to develop a C program able to substitute the original Illegal Instruction trap handler with its own handler. To do that, I think the simplest way is to overwrite the 4 instructions relative to the trap table entry of the Illegal Instruction exception, with new instructions that direct the processor to my handler procedure (the classic jmp).
The problem is that the handler procedure must be a leaf procedure, ended by "rett", and I'm wondering if there's a way to implement that procedure in C (the translation of a C function is a normal procedure, surrounded by the save/restore instructions).
If I may give you one advice: Don't write your trap handler in C code!

The compiler is intended for code generation for applications and not for trap handlers. This implies that it uses many conventions from the SPARC V8 ABI, especially concerning the register usage. For example, the SPARC ABI says that the register %g1 is not expected to retain its content during a procedure call. The called procedure is allowed to overwrite the content. But a trap handler should preserve any registers visible to an application, so it should also preserve %g1! Thus, if you let the compiler choose in which register to put your local variables in your C trap procedure, you cannot guarantee that %g1 is being preserved.

Other problems are the output registers %o0 to %o7. The SPARC register window is circular yielding that the window that is being rotated to by the hardware when the trap occurs may be the last window that is free. Its output registers overlap with the input registers of the last window. "Last" in this contexts means the window that is the oldest one in the register window of the processor that has not yet been saved onto the stack.
Thus, you may only use the outs if you are sure that there is at least one additional free register window available. That means that your trap code should either avoid using the outs at all or you should check the current window pointer (CWP) and the window invalid mask (WIM) if there is another free window available. Only then you are sure that you may use the output registers in your trap code!

Again, the compiler assumes that it can use all outs as it usually can do for application code. This may overwrite other register data and this kind of error is very hard to spot. It is only visible if a trap occurs after your procedure call chain has reached a certain depth (i.e. no more additional register windows free for the application, i.e. any SAVE instruction will cause an overflow trap). It may work for most cases but will sporadically produre strange behaviour. I experienced this kind of bug in my current project some time ago and after long debugging sessions it turned out that it was not my code that was erronous but the trap handler that was written by someone else who was unable to write trap handler code properly.

And - of course - don't use any input registers. These are the output registers of the application where the trap occurs and must be reserved by the trap handler. As the HW is putting the PC and the nPC of the trap in registers %l1 and %l2 of the new window when a trap occurs, the only six registers that your trap handling code may safely use at the beginning are %l0, %l3-%l7. You may then check if there is another register window free and if it is may use additionally the eight output registers as mentioned above.

A third issue with trap handlers are traps itself. If a trap occurs, the processor automatically disables traps, i.e. ET (enable traps) in the PSR (processor status register) is set to zero. That is because the handling of the current trap shall not be interrupted by other traps (especially interrupts) before it didn't finish the current one. Generating another trap while ET is zero will cause the processor to enter error mode (as defined in the SPARC V8 instruction set architecture). This is very dangerous because what follows then is undefined behaviour! The SPARC V8 ISA even mentions that the hardware may typically trigger an external reset for the processor which means that all information of the system is lost! Thus, causing traps itself while being in a trap handler must absolutely b
e avoided!

Therefore, you cannot use the normal register over- or underflow handlers. So don't blindly execute SAVE or RESTORE instructions without checking the WIM before. Don't execute any memory load- or store-instructions if you have an MMU and it is enabled before not checking the page tables (use the LDA instruction with ASI bypass for physical memory addresses to walk the page tables in software before doing ANY normal memory access).

In summary, traps are evil on the SPARC. Write them yourself in assembler and not in C. Or even better: Don't write your own trap handlers if you are unsure of your capabilities and use tested and proven code from someone else (e.g. the Linux kernel). Or try to solve your problems in other ways and avoid writing your own trap handlers if possible. You will shoot youself in the foot if your are not very careful!

regards, matthias



------------------------------------
Josef Ahmad
2010-11-22 09:59:01 UTC
Permalink
Mathias,

Thanks for all the tips! While waiting for somebody to answer my former question, I've reached almost your same conclusion, but your post definitely confirmed my ideas.

The trap handlers must be handwritten in the target assembly in any case, let alone with this weird sparc register arrangement.
I've come across the same - initially unexplainable - odd behaviors you mentioned in your post.
I think that the main pitfall is just the fact that the traps are disabled while executing a trap handler. In this way, it is impossible to nest another trap handler execution (i.e. a window overflow handler), thus avoiding the possibility to use the output registers.
Follows in importance the fact that the "scratch" registers like %g1 must be preserved across the procedure call (as gcc follows its own execution flow which does not plan a jump to the trap handler).

Going into the details, I have to write a handler that will forward a new addtional instruction set (interspersed with the existing v8 ISA) to a coprocessor coupled with the leon3. Unfortunately, this handler has a quite complicated logic (it makes use of translation tables, for example), and I think it will take me a lot of time to implement in sparc assembly, given the fact that I am an absolute beginner with this architecture, and the amount of constraints I have.

I was going to reserve some memory locations to work around the problem of the lack of available registers, but I actually do not know whether the MMU is implemented / active or not in my setup (i'm not the hardware developer). Do you know, by any chance, if the default LEON2/3 setup with leonbare library allows the MMU / paging?

Thanks a lot for your accurate and specific answers,

J.

--- On Sun, 11/21/10, m.rosenfelder <m.rosenfelder-/***@public.gmane.org> wrote:

From: m.rosenfelder <m.rosenfelder-/***@public.gmane.org>
Subject: [leon_sparc] Re: How to install a trap handler
To: leon_sparc-***@public.gmane.org
Date: Sunday, November 21, 2010, 3:54 PM







 













Hey there,
Post by josef_ahm
Could anyone suggest me the best way to install correctly a trap handler at runtime?
I'd like to develop a C program able to substitute the original Illegal Instruction trap handler with its own handler. To do that, I think the simplest way is to overwrite the 4 instructions relative to the trap table entry of the Illegal Instruction exception, with new instructions that direct the processor to my handler procedure (the classic jmp).
The problem is that the handler procedure must be a leaf procedure, ended by "rett", and I'm wondering if there's a way to implement that procedure in C (the translation of a C function is a normal procedure, surrounded by the save/restore instructions).
If I may give you one advice: Don't write your trap handler in C code!



The compiler is intended for code generation for applications and not for trap handlers. This implies that it uses many conventions from the SPARC V8 ABI, especially concerning the register usage. For example, the SPARC ABI says that the register %g1 is not expected to retain its content during a procedure call. The called procedure is allowed to overwrite the content. But a trap handler should preserve any registers visible to an application, so it should also preserve %g1! Thus, if you let the compiler choose in which register to put your local variables in your C trap procedure, you cannot guarantee that %g1 is being preserved.



Other problems are the output registers %o0 to %o7. The SPARC register window is circular yielding that the window that is being rotated to by the hardware when the trap occurs may be the last window that is free. Its output registers overlap with the input registers of the last window. "Last" in this contexts means the window that is the oldest one in the register window of the processor that has not yet been saved onto the stack.

Thus, you may only use the outs if you are sure that there is at least one additional free register window available. That means that your trap code should either avoid using the outs at all or you should check the current window pointer (CWP) and the window invalid mask (WIM) if there is another free window available. Only then you are sure that you may use the output registers in your trap code!



Again, the compiler assumes that it can use all outs as it usually can do for application code. This may overwrite other register data and this kind of error is very hard to spot. It is only visible if a trap occurs after your procedure call chain has reached a certain depth (i.e. no more additional register windows free for the application, i.e. any SAVE instruction will cause an overflow trap). It may work for most cases but will sporadically produre strange behaviour. I experienced this kind of bug in my current project some time ago and after long debugging sessions it turned out that it was not my code that was erronous but the trap handler that was written by someone else who was unable to write trap handler code properly.



And - of course - don't use any input registers. These are the output registers of the application where the trap occurs and must be reserved by the trap handler. As the HW is putting the PC and the nPC of the trap in registers %l1 and %l2 of the new window when a trap occurs, the only six registers that your trap handling code may safely use at the beginning are %l0, %l3-%l7. You may then check if there is another register window free and if it is may use additionally the eight output registers as mentioned above.



A third issue with trap handlers are traps itself. If a trap occurs, the processor automatically disables traps, i.e. ET (enable traps) in the PSR (processor status register) is set to zero. That is because the handling of the current trap shall not be interrupted by other traps (especially interrupts) before it didn't finish the current one. Generating another trap while ET is zero will cause the processor to enter error mode (as defined in the SPARC V8 instruction set architecture). This is very dangerous because what follows then is undefined behaviour! The SPARC V8 ISA even mentions that the hardware may typically trigger an external reset for the processor which means that all information of the system is lost! Thus, causing traps itself while being in a trap handler must absolutely be avoided!



Therefore, you cannot use the normal register over- or underflow handlers. So don't blindly execute SAVE or RESTORE instructions without checking the WIM before. Don't execute any memory load- or store-instructions if you have an MMU and it is enabled before not checking the page tables (use the LDA instruction with ASI bypass for physical memory addresses to walk the page tables in software before doing ANY normal memory access).



In summary, traps are evil on the SPARC. Write them yourself in assembler and not in C. Or even better: Don't write your own trap handlers if you are unsure of your capabilities and use tested and proven code from someone else (e.g. the Linux kernel). Or try to solve your problems in other ways and avoid writing your own trap handlers if possible. You will shoot youself in the foot if your are not very careful!



regards, matthias

























[Non-text portions of this message have been removed]



------------------------------------
m.rosenfelder
2010-11-22 18:42:17 UTC
Permalink
Hello Josef,
Post by Josef Ahmad
Going into the details, I have to write a handler that will forward a new addtional instruction set (interspersed with the existing v8 ISA) to a coprocessor coupled with the leon3. Unfortunately, this handler has a quite complicated logic (it makes use of translation tables, for example), and I think it will take me a lot of time to implement in sparc assembly, given the fact that I am an absolute beginner with this architecture, and the amount of constraints I have.
That sounds interesting as my project does a similar thing. It adds custom instructions to the SPARC V8, but the implementation of these instructions is not in a coprocessor but is being dynamically reconfigured at run-time on an FPGA. If there is no HW implementation for that instruction at instruction execution time, an unimplemented instruction trap occurs and the instruction is being emulated with the basic SPARC V8 instruction set.
Post by Josef Ahmad
I was going to reserve some memory locations to work around the problem of the lack of available registers, but I actually do not know whether the MMU is implemented / active or not in my setup (i'm not the hardware developer).
Yes, maybe you can pin a page of memory which you can then use savely in the trap routines as scratch memory. That should be doable, but memory references can be slow - especially with the write-through and non-write-allocate LEON caches... :-/

I don't know if it is faster but another possibility is to check for availability of another register window and if not then make room for yourself! It's basically the same code as the window overflow handler (see e.g. the Linux kernel handler code in arch/sparc/kernel/etraps.S and entry.S and also include/asm-sparc/winmacro.h). Then you are sure that there is another free register window and you can safely use all eight out registers.
Post by Josef Ahmad
Do you know, by any chance, if the default LEON2/3 setup with leonbare library allows the MMU / paging?
I don't know about the default setup but using an MMU with paging is definitely possible. We do this here to run an adapted Linux 2.6 (snapgear hack for LEON from gaisler). But we still use LEON2 and not 3 because we don't have the time to port our pipeline changes to newer LEON versions (and it's not my decision to make such huge changes to the project).


regards, matthias



------------------------------------
Josef Ahmad
2010-11-23 14:57:25 UTC
Permalink
Thanks for the clarification Matthias, I've collected all your hints and re-designed the trap handler considering what has been discussed, and now I can say that in less than 24 h it is already working!

As regards the probable issue with the MMU / paging layer, I've just checked that the memory access works both with the classical accesses and with the memory mapped IO.

In this preliminary phase I'm not focusing to the performances, I just need a working prototype, and the simulation speaks out.
Nevertheless, I am pretty sure that, in a second moment, I could find very useful the example given by the kernel handler.

Greetings,
Josef

--- On Mon, 11/22/10, m.rosenfelder <m.rosenfelder-/***@public.gmane.org> wrote:

From: m.rosenfelder <m.rosenfelder-/***@public.gmane.org>
Subject: [leon_sparc] Re: How to install a trap handler
To: leon_sparc-***@public.gmane.org
Date: Monday, November 22, 2010, 6:42 PM







 













Hello Josef,
Post by Josef Ahmad
Going into the details, I have to write a handler that will forward a new addtional instruction set (interspersed with the existing v8 ISA) to a coprocessor coupled with the leon3. Unfortunately, this handler has a quite complicated logic (it makes use of translation tables, for example), and I think it will take me a lot of time to implement in sparc assembly, given the fact that I am an absolute beginner with this architecture, and the amount of constraints I have.
That sounds interesting as my project does a similar thing. It adds custom instructions to the SPARC V8, but the implementation of these instructions is not in a coprocessor but is being dynamically reconfigured at run-time on an FPGA. If there is no HW implementation for that instruction at instruction execution time, an unimplemented instruction trap occurs and the instruction is being emulated with the basic SPARC V8 instruction set.
Post by Josef Ahmad
I was going to reserve some memory locations to work around the problem of the lack of available registers, but I actually do not know whether the MMU is implemented / active or not in my setup (i'm not the hardware developer).
Yes, maybe you can pin a page of memory which you can then use savely in the trap routines as scratch memory. That should be doable, but memory references can be slow - especially with the write-through and non-write-allocate LEON caches... :-/



I don't know if it is faster but another possibility is to check for availability of another register window and if not then make room for yourself! It's basically the same code as the window overflow handler (see e.g. the Linux kernel handler code in arch/sparc/kernel/etraps.S and entry.S and also include/asm-sparc/winmacro.h). Then you are sure that there is another free register window and you can safely use all eight out registers.
Post by Josef Ahmad
Do you know, by any chance, if the default LEON2/3 setup with leonbare library allows the MMU / paging?
I don't know about the default setup but using an MMU with paging is definitely possible. We do this here to run an adapted Linux 2.6 (snapgear hack for LEON from gaisler). But we still use LEON2 and not 3 because we don't have the time to port our pipeline changes to newer LEON versions (and it's not my decision to make such huge changes to the project).



regards, matthias
























[Non-text portions of this message have been removed]



------------------------------------

Loading...