Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 05 Mar 2013 20:33:18 +1300
From:      Andrew Turner <andrew@fubar.geek.nz>
To:        Ganbold Tsagaankhuu <ganbold@gmail.com>
Cc:        freebsd-arm@freebsd.org
Subject:   Re: ARM EABI test image
Message-ID:  <20130305203318.24f244c9@bender>
In-Reply-To: <20130304221205.7d427b38@bender>
References:  <20130302172556.5b59e122@bender> <CAGtf9xMcSLpin9oR9eDZdzVnfsT0N6jQowzNq23TAsO9kTqpYA@mail.gmail.com> <20130304221205.7d427b38@bender>

next in thread | previous in thread | raw e-mail | index | archive | help
--MP_/KpoxgBcMnzg5T6o_qvFqvMh
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Mon, 04 Mar 2013 22:12:05 +1300
Andrew Turner <andrew@fubar.geek.nz> wrote:

> On Sun, 3 Mar 2013 01:17:01 +0800
> Ganbold Tsagaankhuu <ganbold@gmail.com> wrote:
> 
> > Andrew,
> > 
> > On Sat, Mar 2, 2013 at 12:25 PM, Andrew Turner
> > <andrew@fubar.geek.nz> wrote:
> > > Hello,
> > >
> > > I have built an updated ARM EABI test image for Raspberry Pi [1].
> > >
> > > The only known issue is c++ exception handling is broken when
> > > using in a dynamically linked executable. Static executables
> > > should work with c++ exceptions.
> > >
> > > To test it you will have to extract it using unxz and dd it to an
> > > sd card, for example, with a USB to SD adapter on /dev/da0:
> > > $ unxz bsd-pi-eabi-r247609.img.xz
> > > $ dd if=bsd-pi-eabi-r247609.img of=/dev/da0
> > >
> > > If you don't have a Raspberry Pi but would like to try it on your
> > > board you can add -DWITH_ARM_EABI to the make commands you use to
> > > build and install world and the kernel.
> > >
> > > Can people try this as I would like to know if anything else is
> > > broken as this will become the default ABI for 10.
> > >
> > 
> > Just tried the image. Seems work but observed for instance gpart
> > shows big numbers for 2GB SD:
> 
> I've confirmed this is a bug where the stack is incorrectly aligned. I
> have a fix for this and will post a patch for review when I've cleaned
> it up.

Can you try this patch. It fixes the alignment of the stack in the
kernel to be on an 8 byte boundary.

Andrew
--MP_/KpoxgBcMnzg5T6o_qvFqvMh
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=stack_align.diff

Index: arm/vm_machdep.c
===================================================================
--- arm/vm_machdep.c	(revision 247608)
+++ arm/vm_machdep.c	(working copy)
@@ -73,6 +73,12 @@
 
 #include <machine/md_var.h>
 
+/*
+ * struct switchframe must be a multiple of 8 for correct stack alignment
+ */
+CTASSERT(sizeof(struct switchframe) == 24);
+CTASSERT(sizeof(struct trapframe) == 76);
+
 #ifndef NSFBUFS
 #define NSFBUFS		(512 + maxusers * 16)
 #endif
@@ -131,8 +137,8 @@
 	pcb2->un_32.pcb32_sp = td2->td_kstack +
 	    USPACE_SVC_STACK_TOP - sizeof(*pcb2);
 	pmap_activate(td2);
-	td2->td_frame = tf =
-	    (struct trapframe *)pcb2->un_32.pcb32_sp - 1;
+	td2->td_frame = tf = (struct trapframe *)STACKALIGN(
+	    pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
 	*tf = *td1->td_frame;
 	sf = (struct switchframe *)tf - 1;
 	sf->sf_r4 = (u_int)fork_return;
@@ -142,6 +148,8 @@
 	tf->tf_r0 = 0;
 	tf->tf_r1 = 0;
 	pcb2->un_32.pcb32_sp = (u_int)sf;
+	KASSERT((pcb2->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_fork: Incorrect stack alignment"));
 
 	/* Setup to release spin count in fork_exit(). */
 	td2->td_md.md_spinlock_count = 1;
@@ -345,6 +353,8 @@
 	tf->tf_r0 = 0;
 	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
 	td->td_pcb->un_32.pcb32_und_sp = td->td_kstack + USPACE_UNDEF_STACK_TOP;
+	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_set_upcall: Incorrect stack alignment"));
 
 	/* Setup to release spin count in fork_exit(). */
 	td->td_md.md_spinlock_count = 1;
@@ -438,6 +448,8 @@
 	sf->sf_r4 = (u_int)func;
 	sf->sf_r5 = (u_int)arg;
 	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
+	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
+	    ("cpu_set_fork_handler: Incorrect stack alignment"));
 }
 
 /*
Index: arm/swtch.S
===================================================================
--- arm/swtch.S	(revision 247608)
+++ arm/swtch.S	(working copy)
@@ -211,10 +211,12 @@
 	GET_PCPU(r6)
 	str	r7, [r6, #PC_CURPCB]
 
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 
 ENTRY(cpu_switch)
 	stmfd	sp!, {r4-r7, lr}
+	sub	sp, sp, #4;
 	mov	r6, r2 /* Save the mutex */
 
 .Lswitch_resume:
@@ -488,6 +490,7 @@
 	 * Pull the registers that got pushed when either savectx() or
 	 * cpu_switch() was called and return.
 	 */
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 #ifdef DIAGNOSTIC
 .Lswitch_bogons:
@@ -501,6 +504,7 @@
 #endif
 ENTRY(savectx)
 	stmfd   sp!, {r4-r7, lr}
+	sub	sp, sp, #4
 	/*
 	 * r0 = pcb
 	 */
@@ -528,6 +532,7 @@
 	bl	_C_LABEL(vfp_store)
 1:
 #endif		/* ARM_VFP_SUPPORT */
+	add	sp, sp, #4;
 	ldmfd	sp!, {r4-r7, pc}
 
 ENTRY(fork_trampoline)
Index: include/frame.h
===================================================================
--- include/frame.h	(revision 247608)
+++ include/frame.h	(working copy)
@@ -138,10 +138,14 @@
 } irqframe_t;
 
 /*
- * Switch frame
+ * Switch frame.
+ *
+ * It is important this is a multiple of 8 bytes so the stack is correctly
+ * aligned when we create new threads.
  */
 
 struct switchframe {
+	u_int	pad;	/* Used to pad the struct to a multiple of 8-bytes */
 	u_int	sf_r4;
 	u_int	sf_r5;
 	u_int	sf_r6;

--MP_/KpoxgBcMnzg5T6o_qvFqvMh--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130305203318.24f244c9>