GP2X Alignment Problems


ldesnogu

Well-Known Member
Joined
Dec 26, 2006
Messages
1,049
Age
56
Location
France
Website
Visit site
There is something wrong going on with alignment:

Code:
[root@gp2x /]$cat /proc/cpu/alignment
User:		   1
System:		 32108
Skipped:		0
Half:		   1
Word:		   32107
Multi:		  0
User faults:	0 (ignored)
[root@gp2x /]$cat /proc/cpu/alignment
User:		   1
System:		 32210
Skipped:		0
Half:		   1
Word:		   32209
Multi:		  0
User faults:	0 (ignored)
[root@gp2x /]$cat /proc/cpu/alignment
User:		   1
System:		 32312
Skipped:		0
Half:		   1
Word:		   32311
Multi:		  0
User faults:	0 (ignored)

Basically this means there are many unaligned accesses to memory and that they are not fixed (the User faults value of 0 means: don't fix for user programs).
So many (fixed) unaligned accesses occur while in system mode.
Anyone tried to dig into that to find the culprit?
 
Hmmm , complaining that 32 bit accesses are not 4 byte aligned (based on the changes in the counters in System and Word). I would think it would be data not instructions because the mess up of the bits for instructions would tend to be more fatal.

Is this something where all you did was do sequential "cats"?
 
rixed posted on Dec 29 2006 at 06:20 PM said:
Interresting. I was not aware of such a trick.
Let's turn this of off to see what Oops first :)
Well this won't break the kernel since it always correct alignment faults.
Here is a test program and its outputs (this should answer Gary's question ;)):

Code:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define BUF_SIZE  1024

typedef struct {
  int User;
  int System;
  int Skipped;
  int Half;
  int Word;
  int Multi;
  int User_faults;
} proc_align_t;

static
void dump_proc(FILE *fout)
{
  const char   *name = "/proc/cpu/alignment";
  static char   buf[BUF_SIZE];
  FILE		 *fin;
  int		   line_nb;
  proc_align_t  align;

  fin = fopen(name, "r");
  if (fin == NULL) {
	fprintf(stderr, "Could not open file <%s>\n", name);
	return;
  }
  line_nb = 0;
  while (fgets(buf, BUF_SIZE, fin)) {
	const char *p_buf;
	int		 data;

	for (p_buf = buf; *p_buf != '\0' && *p_buf != ':'; p_buf++)
	 ;
	if (*p_buf != '\0')
	  p_buf++;
	sscanf(p_buf, "%d", &data);
	switch (line_nb) {
	case 0: align.User		= data; break;
	case 1: align.System	  = data; break;
	case 2: align.Skipped	 = data; break;
	case 3: align.Half		= data; break;
	case 4: align.Word		= data; break;
	case 5: align.Multi	   = data; break;
	case 6: align.User_faults = data; break;
	default:
	  fprintf(stderr, "??? spurious %s", buf);
	}
	line_nb++;
  }
  fclose(fin);
  fprintf(fout, "%d %d (%d+%d+%d+%d) %d\n",
	  align.User,
	  align.System,
	  align.Skipped,
	  align.Half,
	  align.Word,
	  align.Multi,
	  align.User_faults);
}

uint64_t a;

int main(int argc, const char *argv[])
{
  uint8_t *ptr;

  printf("Hello\n");
  ptr = (uint8_t *)&a;

  printf("### Two reads of /proc/cpu/alignment\n");
  dump_proc(stdout);
  dump_proc(stdout);

  printf("### Two reads of /proc/cpu/alignment separated by a printf\n");
  dump_proc(stdout);
  printf("--- the print\n");
  dump_proc(stdout);

  printf("### Aligned store\n");

  a = 0x123456789abcdef0ull;
  *(uint32_t *)ptr = 0xcafebabe;
  dump_proc(stdout);
  printf("val=%016llx\n", a);

  printf("### Unaligned store\n");

  a = 0x123456789abcdef0ull;
  *(uint32_t *)(ptr+1) = 0xcafebabe;
  dump_proc(stdout);
  printf("val=%016llx\n", a);

  a = 0x123456789abcdef0ull;
  *(uint32_t *)(ptr+2) = 0xcafebabe;
  dump_proc(stdout);
  printf("val=%016llx\n", a);

  a = 0x123456789abcdef0ull;
  *(uint32_t *)(ptr+3) = 0xcafebabe;
  dump_proc(stdout);
  printf("val=%016llx\n", a);

  return 0;
}

Output with default alignment:

Code:
Hello
### Two reads of /proc/cpu/alignment
55 41668 (0+1+41670+0) 0
55 41685 (0+1+41687+0) 0
### Two reads of /proc/cpu/alignment separated by a printf
55 41702 (0+1+41704+0) 0
--- the print
55 41753 (0+1+41755+0) 0
### Aligned store
55 41770 (0+1+41772+0) 0
val=12345678cafebabe
### Unaligned store
56 41838 (0+1+41840+0) 0
val=12345678cafebabe
57 41855 (0+1+41857+0) 0
val=12345678cafebabe
58 41906 (0+1+41908+0) 0
val=12345678cafebabe

Output after echo 2 >/proc/cpu/alignment

Code:
Hello
### Two reads of /proc/cpu/alignment
58 42552 (0+1+42554+0) 2
58 42552 (0+1+42554+0) 2
### Two reads of /proc/cpu/alignment separated by a printf
58 42586 (0+1+42588+0) 2
--- the print
58 42620 (0+1+42622+0) 2
### Aligned store
58 42671 (0+1+42673+0) 2
val=12345678cafebabe
### Unaligned store
59 42705 (0+1+42708+0) 2
val=123456cafebabef0
60 42739 (0+1+42743+0) 2
val=1234cafebabedef0
61 42790 (0+1+42795+0) 2
val=12cafebabebcdef0

Output after echo 4 >/proc/cpu/alignment

Code:
Hello
### Two reads of /proc/cpu/alignment
61 43334 (0+1+43339+0) 4
61 43334 (0+1+43339+0) 4
### Two reads of /proc/cpu/alignment separated by a printf
61 43334 (0+1+43339+0) 4
--- the print
61 43334 (0+1+43339+0) 4
### Aligned store
61 43334 (0+1+43339+0) 4
val=12345678cafebabe
### Unaligned store
Bus error
 
Last edited by a moderator:
Gary Miller posted on Dec 29 2006 at 07:54 PM said:
Hmmm , complaining that 32 bit accesses are not 4 byte aligned (based on the changes in the counters in System and Word). I would think it would be data not instructions because the mess up of the bits for instructions would tend to be more fatal.
The alignment is checked only for data accesses. For instructions there are various rules that prevent unalignment (some instructions will switch to/from Thumb mode, others will ignore lower bits, or it can be UNPREDICTABLE).

What frightens me is that the kernel or one of the drivers is doing these accesses. Anyone to patch arch/arm/mm/alignment.c so that it dumps information? :D
 
Last edited by a moderator:
Laurent posted on Dec 29 2006 at 08:15 PM said:
rixed posted on Dec 29 2006 at 06:20 PM said:
Interresting. I was not aware of such a trick.
Let's turn this of off to see what Oops first :)
Well this won't break the kernel since it always correct alignment faults.

No way to ask the module to stop fixing the access ? like echo 0 > /proc.alignment ?
 
Last edited by a moderator:
rixed posted on Dec 29 2006 at 10:19 PM said:
No way to ask the module to stop fixing the access ? like echo 0 > /proc.alignment ?
No, the kernel fixes its unaligned accesses no matter the setting, which BTW is already set as 0 (it's the User Faults value displayed).
For more information look here: http://svn.gp2x.com/gp2x/tag/kernel/2.1.x/.../mm/alignment.c

The more I think about it, the more I think there are only two ways to track that bug:
1. add a printk to alignment.c
2. boot the kernel through a simulator.

The second solution would need some work to get some basic emulation of the various chips. Even though very basic emulation would be enough, it would nonetheless represents a high amount of work.

The first solution requires kernel recompilation. Has anyone already tried to recompile the kernel using what GPH open sourced?
 
Last edited by a moderator:
Laurent posted on Dec 29 2006 at 10:48 PM said:
No, the kernel fixes its unaligned accesses no matter the setting, which BTW is already set as 0 (it's the User Faults value displayed).
For more information look here: http://svn.gp2x.com/gp2x/tag/kernel/2.1.x/.../mm/alignment.c

Strange design decision.

The more I think about it, the more I think there are only two ways to track that bug:
1. add a printk to alignment.c
2. boot the kernel through a simulator.
The second solution would need some work to get some basic emulation of the various chips. Even though very basic emulation would be enough, it would nonetheless represents a high amount of work.

This is a work for Vimacs gp2x emulator !
 
Last edited by a moderator:
rixed posted on Dec 30 2006 at 10:27 AM said:
Laurent posted on Dec 29 2006 at 10:48 PM said:
No, the kernel fixes its unaligned accesses no matter the setting, which BTW is already set as 0 (it's the User Faults value displayed).
Strange design decision.
You should take the historic point of view: ARM cores used to accept unaligned accesses by default; then ARM moved to more powerful cores the behaviour was changed, but there already was some existing code base. To ease Linux porting, I guess it was decided that the kernel should correct its and drivers' unaligned accesses transparently :)

However I agree we should get rid of these unaligned accesses!
This is a work for Vimacs gp2x emulator !
You mean there is some work going on there? Any link?
 
Last edited by a moderator:
rokdcasbah posted on Dec 30 2006 at 10:54 PM said:
i think he's kidding...although squidge was working on one a while back. not sure how far he got.

Oh, sorry, that was Squidge and not Vimacs ? Anyway, at that time his emulator could run well enought to complete the linux boot
sequence, which may be enought to spot the guilty code.

The emulator was never released, anyway. Better ask him privately.
 
Last edited by a moderator:
Interesting, I don't handle alignment issues in my emu - I don't call the unaligned vector, I just return garbage. Maybe this is why is why it crashes for some unknown reason that I've not been able to find and thus gave up on?

Something to investigate!
 
I love this thread. I didn't know about this earlier, and googled to find;
echo 2 > /proc/cpu/alignment
This fixed fasttracker for modplug, if only i knew this earlier!
Of course, not a good way to solve the problem, but the unaligned reads are eeeeverywhere in libmodplug. I've fixed at least a few hundred in the source by now, but there are still bugs left.
(it only has problem when loading the xm files, so it doesnt hurt performance that bad)
 
Orkie posted on Dec 31 2006 at 05:34 PM said:
Thanks for the link.

I followed the procedure and used gcc 2.95.3 from Neophob.
I checked out GPH kernel (revision 33).

What bothers me is that the resulting image is not the same as the one provided by GPH:

Code:
 632985 Apr 20  2006 Firmware/2.0.0/gp2xkernel.img
 618270 Sep 21 20:08 Firmware/2.1.0/gp2xkernel.img
 618526 Oct 30 17:12 Firmware/2.1.1/gp2xkernel.img
 639956 Jan  1 17:45 gp2xkernel.img <- mine
This could be because GPH does not build with same compiler or .config file provided in their SVN.

Anyway I won't try hacking the kernel until I can build the same image as GPH...
 
Last edited by a moderator:
I don't think anyone has gotten a kernel image exactly the same, probably a different compiler or something. Someone proving me wrong wouldn't be a bad thing though :)
 
I don't think anyone has gotten a kernel image exactly the same, probably a different compiler or something. Someone proving me wrong wouldn't be a bad thing though :)
Well I have already found that NBD support should not be in.
It will be a long and painful process but I have already done it in the past for another platform, so I have hopes :D
 
Last edited by a moderator:
If you install art103's version of u-boot, you can boot a kernel off your SD card. It should make it easier for you to test with.
 
Back
Top