summaryrefslogtreecommitdiffstats
path: root/sys/boot/ia64/ski/ssc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/ia64/ski/ssc.c')
-rw-r--r--sys/boot/ia64/ski/ssc.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/boot/ia64/ski/ssc.c b/sys/boot/ia64/ski/ssc.c
index 11a91c8..e3e9eb2 100644
--- a/sys/boot/ia64/ski/ssc.c
+++ b/sys/boot/ia64/ski/ssc.c
@@ -29,14 +29,24 @@
#include <stand.h>
#include "libski.h"
+/*
+ * Ugh... Work around a bug in the Linux version of ski for SSC_GET_RTC. The
+ * PSR.dt register is not preserved properly and causes further memory
+ * references to be done without translation. All we need to do is preserve
+ * PSR.dt across the SSC call. We do this by saving and restoring psr.l
+ * completely.
+ */
u_int64_t
ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, int which)
{
+ register u_int64_t psr;
register u_int64_t ret0 __asm("r8");
+ __asm __volatile("mov %0=psr;;" : "=r"(psr));
__asm __volatile("mov r15=%1\n\t"
- "break 0x80000"
+ "break 0x80000;;"
: "=r"(ret0)
: "r"(which), "r"(in0), "r"(in1), "r"(in2), "r"(in3));
+ __asm __volatile("mov psr.l=%0;; srlz.d" :: "r"(psr));
return ret0;
}
OpenPOWER on IntegriCloud