NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
port-evbarm/40136: Gumstix startup code uses wrong registers
>Number: 40136
>Category: port-evbarm
>Synopsis: Gumstix startup code uses wrong registers
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: port-evbarm-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Dec 08 23:55:00 +0000 2008
>Originator: Brett Slager
>Release: NetBSD current Dec 7, 2008
>Organization:
>Environment:
Same
>Description:
The code to handle argc and argvs passed from u-boot is getting them
from the wrong registers. The AAPCS states the first 4 arguments to a
procedure call go in the first 4 registers r0-r4. Instead of getting argc
from r0 and argvs from r1, r6 and r5 are used which are local variables left
over from the do_go() function in u-boot. If the way this function is
compiled in u-boot changes, and an updated u-boot is installed, netbsd gumstix
could fail to get the proper arguments.
>How-To-Repeat:
Inspect the code:
src/sys/arch/evbarm/gumstix/gumstix_start.S
src/sys/arch/evbarm/gumstix/gumstix_machdep.c
and the following from u-boot:
...code snip from u-boot...
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
addr = simple_strtoul(argv[1], NULL, 16);
printf ("## Starting application at 0x%08lX ...\n", addr);
.
.
.
rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
...end code snip from u-boot...
Instrument the startup to save and print the initial register values.
Note the following:
...test boot output...
GUM> fatload ide 0 0xa0200000 testimg
reading testimg
3920780 bytes read
GUM> go 0xa0200000 garbage args extrastuff busheader=netcf
## Starting application at 0xA0200000 ...
NetBSD/evbarm (gumstix) booting ...
system serial: 0x06668d0053456883
Regs: r0=5, r1=a3ee0334, r2=1, r3=40100000 r4=a0200000, r5=a3ee0334, r6=6
...end test boot output...
Note that r0 (argc) has the right number of arguments...
>Fix:
We really only need the first two arguments, but I left the code
saving all four - they may be useful later on if we get different booting
support.
(Tested and works on Gumstix connex board using slightly older source - today's
wouldn't get very far past the argument processing due to:
vmem_check_sanity: overlapping VMEM 'kmem' span 0xc1c8d000 - 0xc1c8e000 free
vmem_check_sanity: overlapping VMEM 'kmem' span 0xc1c8d000 - 0xc1c8e000 free
panic: kernel diagnostic assertion "vmem_check_sanity(vm)" failed: file
"/home/bds/src/netbsd/builds/0007/src/sys/kern/subr_vmem.c", line 1060)
Index: gumstix_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/gumstix/gumstix_start.S,v
retrieving revision 1.5
diff -u -p -r1.5 gumstix_start.S
--- gumstix_start.S 17 Oct 2007 19:54:12 -0000 1.5
+++ gumstix_start.S 7 Dec 2008 23:57:33 -0000
@@ -97,11 +97,11 @@ _C_LABEL(gumstix_start):
* in VA 0xc0200000..
*/
/* save u-boot's args */
- adr r0, u_boot_args
+ adr r4, u_boot_args
nop
nop
nop
- stmia r0!, {r3, r4, r5, r6}
+ stmia r4!, {r0, r1, r2, r3}
nop
nop
nop
@@ -151,7 +151,7 @@ Lstartup_pagetable:
.globl _C_LABEL(u_boot_args)
u_boot_args:
- .space 16 /* r3, r4, r5, r6 */
+ .space 16 /* r0, r1, r2, r3 */
#define MMU_INIT(va,pa,n_sec,attr) \
Index: gumstix_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/gumstix/gumstix_machdep.c,v
retrieving revision 1.12
diff -u -p -r1.12 gumstix_machdep.c
--- gumstix_machdep.c 18 Nov 2008 18:20:10 -0000 1.12
+++ gumstix_machdep.c 7 Dec 2008 23:57:52 -0000
@@ -447,7 +447,7 @@ initarm(void *arg)
{
extern vaddr_t xscale_cache_clean_addr;
extern uint32_t *u_boot_args[];
- enum { r3 = 0, r4 = 1, r5 = 2, r6 = 3 }; /* args from u-boot */
+ enum { r0 = 0, r1 = 1, r2 = 2, r3 = 3 }; /* args from u-boot */
int loop;
int loop1;
u_int l1pagetable;
@@ -505,7 +505,7 @@ initarm(void *arg)
* Examine the boot args string for options we need to know about
* now.
*/
- process_kernel_args((int)u_boot_args[r6], (char **)u_boot_args[r5]);
+ process_kernel_args((int)u_boot_args[r0], (char **)u_boot_args[r1]);
memstart = 0xa0000000UL;
memsize = 0x04000000UL; /* 64MB */
@@ -927,13 +927,6 @@ process_kernel_args(int argc, char *argv
boothowto = 0;
- /*
- * XXXXX: The value of argc is wrong. The number of arguments is
- * corrected in the do_go() of u-boot. However, it is not actually
- * corrected.
- */
- argc --;
-
for (i = 1, j = 0; i < argc; i++) {
if (!strncmp(argv[i], busheader_name, strlen(busheader_name))) {
/* configure for GPIOs of busheader side */
Home |
Main Index |
Thread Index |
Old Index