Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
12748 Discussions

Exception Handler for misaligned data memory access

Altera_Forum
Honored Contributor II
3,583 Views

Hi All, 

 

I'm after some help... Does anybody have available or point me in the direction of a worked example of an exception handler which processes NIOS2_EXCEPTION_MISALIGNED_DATA_ADDR exception cause. 

 

I have many packed data structures (in our 10'000s lines of existing code) which I access using pointers. 

 

As way of explaining what I need to achieve, 

 

struct PackedStruct { 

 

alt_u8 A; 

alt_u16 B; // not aligned  

 

}__attribute((__packed__)) ; 

 

struct PackedStruct Packed; 

 

int main() 

alt_u16 *u16ptr; 

alt_u16 Value; 

 

// register my exception handler 

alt_instruction_exception_register (MisalignedServiceRoutine); 

 

u16ptr = Packed.B; 

Value = *u16ptr; // this generates an exception 

 

I don't know how to code my exception handler so that I can do a byte memcpy and then resume. 

 

I guess I need to look to see if the instruction which caused the exception was a Load or a Store unsigned/signed half word, full word. Then do the memory copy. The problem is I don't know how to do this. Can anybody help. 

 

Just to confirm, I have generated a SOF with the a nios II/f with misaligned memory access and extra exception information options checked under Excpetion checking. My NIOS SBT project works to the point whereby my exception handler is run when a misaligned data memory access occurs. 

 

Thanks in advance. 

Ade
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
2,131 Views

I'm not sure that you'll find it easy to emulate the mis-aligned transfer in the ISR. You'll need to look at the interrupted instruction and 'hand' decode it, then get the appropriate register values from the saved registers to preform the required memory transfers. 

 

You are better off shooting the person who used 'packed' for the structures! 

 

One option might be to encapsulate the misaligned 'int' in a structure. Then fix all the code (changing the type of the pointer, and using access defines) so that the code compiles. The compiler will then generate the required code for the misaligned accesses. 

 

I don't think it is possible to generate a 'pointer to a misaligned int', you can only have misaligned structure members. 

It is also possible to the __attribute__((aligned(1))) to mark single structure 

members as having bytes alignment while still assuming the structure itself is aligned - ie not forcing misaligned accesses on all fields. 

(Also useful to force an alignment of 2)
0 Kudos
Altera_Forum
Honored Contributor II
2,131 Views

Thanks for the response. Yeah, I agree it looks like I will have to ‘hand’ decode the instructions – the problem is assembler code is not my strength.  

 

As for defining the structures as ‘packed’ – the fact is that the vast majority of the existing code originates from the days when 8-bit processors were the norm. The structures were not defined as packed.. all elements were 8-bit aligned by virtue of the underlying architecture. Moving to a 32-bit processor simply breaks the existing code. 

 

Not sure shooting the person who original wrote the code is an option! Maybe holding a large stick to whoever wrote the Nios II compiler whilst pointing out (no pun intended) that they should provide a way of dealing with this situation. As way of an example they should take a look at Altium’s Tasking compiler for the Nios II. This provides a way of declaring pointers as unaligned which then forces the linker to generate byte access code – simple. Unfortunately Altium has pulled support for the Tasking compiler so it can’t be used with the latest Cyclone FPGAs, Quartus etc.  

 

That said I’m confident that the misaligned memory access exception is Altera’s intended solution to this situation. Ideally, I was hoping that there was a fully worked example. Failing that it would be nice to get confirmation that the exception handler is a workable solution in which case I can start to get to grips with the necessary assembly code.
0 Kudos
Altera_Forum
Honored Contributor II
2,131 Views

GCC generate the code to do multiple bus cycles to access misaligned data for members of 'packed' structures and structure members with alignment constraint, however it won't let you define a 'pointer to packed int'. 

 

The following does work (retyped): 

typedef struct { int v; } __attribute__((packed)) packed_int; struct foo { char x; packed_int y; }; int bar(foo *z) { packed_int *p = &z->y; return p->v; }
0 Kudos
Altera_Forum
Honored Contributor II
2,131 Views

I agree about the compiler option. Sometimes you have no choice but to use old existing code that has already been paid for and it is not commercially viable to re-write for larger processors. 

 

Keil compilers give the option of using a PRAGMA to wrap code that needs to be forced to compile with byte access. Why can't Altera do this ? 

 

Out of interest I raised this 2 and a half years ago with them and was told that they were going to implement it in the avalon fabric, but nothing has ever materialized.
0 Kudos
Altera_Forum
Honored Contributor II
2,131 Views

One of the problems supporting misaligned transfers is that you can get a TLB miss and/or page fault (or even an external bus error) when accessing the second word. This is rather problematical to deal with properly - especially for writes and what are supposed to be locked bus transfers (which the nios and the Avalon MM bus don't support). 

 

It might be worth looking at the code generated by gcc for sparc - to see if it can generate multiple memory accesses for pointers to 'packed' integers. If it does (or possibly anyway!) it might be possible to modify gcc's code generatotor to detect the 'packed' property and perform the required cycles. 

 

For someone who understands gcc code generation that probably isn't that hard!
0 Kudos
Reply