summaryrefslogtreecommitdiff
path: root/sys/arch/alpha
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-09-30 19:43:45 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-09-30 19:43:45 +0000
commitb5b1b4323c189d6ba70ad96398d88bae0d54647f (patch)
tree26446024c07fecd49a8c0802777228b0d44aca35 /sys/arch/alpha
parent972c3d722dcbd0f859155224a937bcff54d82014 (diff)
Some old SRM require 8-byte alignment of the buffer passed to the prom
getenv routine, so fulfill this requirement. From NetBSD. (Note this only concerns the boot blocks, as the kernel itself uses extremely well aligned addresses for getenv calls).
Diffstat (limited to 'sys/arch/alpha')
-rw-r--r--sys/arch/alpha/stand/prom.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/arch/alpha/stand/prom.c b/sys/arch/alpha/stand/prom.c
index 8216b831246..57627f02900 100644
--- a/sys/arch/alpha/stand/prom.c
+++ b/sys/arch/alpha/stand/prom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: prom.c,v 1.6 2009/09/30 19:41:59 miod Exp $ */
+/* $OpenBSD: prom.c,v 1.7 2009/09/30 19:43:44 miod Exp $ */
/* $NetBSD: prom.c,v 1.2 1996/11/25 16:18:16 cgd Exp $ */
/*
@@ -91,12 +91,23 @@ prom_getenv(id, buf, len)
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--;
+ if (len > ret.u.retval)
+ len = ret.u.retval;
+ memcpy(buf, abuf, len);
+ buf[len] = '\0';
- return (ret.u.retval);
+ return (len);
}