Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/stand/common Experimentation reveals that the...



details:   https://anonhg.NetBSD.org/src/rev/1263db360264
branches:  trunk
changeset: 534610:1263db360264
user:      nathanw <nathanw%NetBSD.org@localhost>
date:      Tue Jul 30 20:36:42 2002 +0000

description:
Experimentation reveals that the implementation of GET_ENV on at least
some systems chokes if the buffer is not 8-byte aligned. GCC only aligns
character arrays to 4-byte boundaries by default, so it's possible to get
unlucky and die in the boot blocks with a "kernel stack not valid halt".

Avoid the problem by using a local, aligned buffer as the argument to GET_ENV,
and copying the result into the caller's buffer.

Should fix PRs port-alpha/17682 and port-alpha/17717.
CVS ----------------------------------------------------------------------

diffstat:

 sys/arch/alpha/stand/common/prom.c |  19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diffs (43 lines):

diff -r bee698d0d8c0 -r 1263db360264 sys/arch/alpha/stand/common/prom.c
--- a/sys/arch/alpha/stand/common/prom.c        Tue Jul 30 19:41:08 2002 +0000
+++ b/sys/arch/alpha/stand/common/prom.c        Tue Jul 30 20:36:42 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: prom.c,v 1.10 1999/04/02 03:11:57 cgd Exp $ */
+/* $NetBSD: prom.c,v 1.11 2002/07/30 20:36:42 nathanw Exp $ */
 
 /*  
  * Mach Operating System
@@ -26,6 +26,8 @@
  * the rights to redistribute these changes.
  */
 
+#include <lib/libkern/libkern.h>
+
 #include <sys/types.h>
 
 #include <machine/prom.h>
@@ -125,12 +127,21 @@
        int id, len;
        char *buf;
 {
+       /* 
+        * On at least some systems, the GETENV call requires a
+        * 8-byte-aligned buffer, or it bails out with a "kernel stack
+        * not valid halt". Provide a local, aligned buffer here and
+        * then copy to the caller's buffer.
+        */
+       static char abuf[128] __attribute__((aligned (8)));
        prom_return_t ret;
 
-       ret.bits = prom_dispatch(PROM_R_GETENV, id, buf, len-1);
+       ret.bits = prom_dispatch(PROM_R_GETENV, id, abuf, 128);
        if (ret.u.status & 0x4)
                ret.u.retval = 0;
-       buf[ret.u.retval] = '\0';
+       len = min(len - 1, ret.u.retval);
+       memcpy(buf, abuf, len);
+       buf[len] = '\0';
 
-       return (ret.u.retval);
+       return (len);
 }



Home | Main Index | Thread Index | Old Index