Unaligned 64-bits access on FreeBSD/powerpc

Maxim Sobolev sobomax at FreeBSD.org
Thu Aug 3 18:59:31 UTC 2006


Peter Grehan wrote:
>> Well, actually *nix has a long history of just killing the program 
>> with SIGBUS in such case.
>>
>> I am just wondering if it's really expected behavior on 
>> FreeBSD/powerpc or not.
> 
>  No :(
> 
>  What system are you running on ? I was pretty sure that G3/G4 CPUs 
> allowed unaligned accesses unless you explicitly disabled it (except for 
> cases such as vector ops). A 64 bit op on these CPUs should decompose 
> into separate 32-bit accesses ala i386 so the same case should occurr 
> for unaligned 32-bit ops.
> 
>  In any event, the default should be that unaligned accesses are 
> handled, and then have switches to optionally uprintf the address, or 
> SIGBUS.

It's G4 (Mac Mini). Dmesg reports processor as:

cpu0: Motorola PowerPC 7447A revision 1.2, 1250.00 MHz
cpu0: HID0 8450c0bc<EMCP,TBEN,NAP,DPM,ICE,DCE,SGE,BTIC,LRSTK,FOLD,BHT>

According to the following link, unaligned floating-point 64-bits access 
isn't supported in the PowerPC:

http://www-128.ibm.com/developerworks/library/pa-dalign/

I use the following program to reproduce the problem. It dies with 
"failure doing 64-bit access at address 0x7fffd8e1".

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>

static char *atype;
static uint8_t *apoint;

static void
sigbus(int signum)
{

     printf("failure doing %s-bit access at address %p\n", atype, apoint);
     exit(1);
}

int
main()
{
         uint8_t buf[1024];
         uint16_t v16;
         uint32_t v32;
         uint64_t v64;
         static int i;

         signal(SIGBUS, sigbus);

         atype = "16";
         for (i = 0; i < 256; i++) {
             apoint = (uint8_t *)&(buf[i]);
             v16 = *(uint16_t *)apoint;
         }
         atype = "32";
         for (i = 0; i < 256; i++) {
             apoint = (uint8_t *)&(buf[i]);
             v32 = *(uint32_t *)apoint;
         }
         atype = "64";
         for (i = 0; i < 256; i++) {
             apoint = (uint8_t *)&(buf[i]);
             v64 = *(uint64_t *)apoint;
         }
         exit(0);
}

-Maxim


More information about the freebsd-ppc mailing list