From eb06360f04a96fb0010bd0b774f305693bc2040d Mon Sep 17 00:00:00 2001
From: Doug Rabson <dfr@FreeBSD.org>
Date: Sat, 12 Feb 2000 14:57:01 +0000
Subject: [PATCH] Add functions which allow i/o memory to be accessed without
 forcing a memory barrier (needed for XFree86 4.0).

Approved by: jkh
---
 lib/libio/bwx.c         |  6 +++---
 lib/libio/io.c          | 25 +++++++++++++++++++++++--
 sys/alpha/include/bwx.h | 19 +++++++++++++++++++
 3 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/lib/libio/bwx.c b/lib/libio/bwx.c
index bc3bbb31d629..dede88184801 100644
--- a/lib/libio/bwx.c
+++ b/lib/libio/bwx.c
@@ -206,21 +206,21 @@ static void
 bwx_writeb(void *handle, u_int32_t offset, u_int8_t val)
 {
     struct bwx_mem_handle *h = handle;
-    stb((vm_offset_t)h->virt1 + offset, val);
+    stb_nb((vm_offset_t)h->virt1 + offset, val);
 }
 
 static void
 bwx_writew(void *handle, u_int32_t offset, u_int16_t val)
 {
     struct bwx_mem_handle *h = handle;
-    stw((vm_offset_t)h->virt2 + offset, val);
+    stw_nb((vm_offset_t)h->virt2 + offset, val);
 }
 
 static void
 bwx_writel(void *handle, u_int32_t offset, u_int32_t val)
 {
     struct bwx_mem_handle *h = handle;
-    stl((vm_offset_t)h->virt4 + offset, val);
+    stl_nb((vm_offset_t)h->virt4 + offset, val);
 }
 
 struct io_ops bwx_io_ops = {
diff --git a/lib/libio/io.c b/lib/libio/io.c
index 7abfa36f6ff2..3ccce2e4b32a 100644
--- a/lib/libio/io.c
+++ b/lib/libio/io.c
@@ -119,17 +119,38 @@ readl(void *handle, u_int32_t offset)
 void
 writeb(void *handle, u_int32_t offset, u_int8_t val)
 {
-    return ops->writeb(handle, offset, val);
+    ops->writeb(handle, offset, val);
+    __asm__ __volatile__ ("mb");
 }
 
 void
 writew(void *handle, u_int32_t offset, u_int16_t val)
 {
-    return ops->writew(handle, offset, val);
+    ops->writew(handle, offset, val);
+    __asm__ __volatile__ ("mb");
 }
 
 void
 writel(void *handle, u_int32_t offset, u_int32_t val)
+{
+    ops->writel(handle, offset, val);
+    __asm__ __volatile__ ("mb");
+}
+
+void
+writeb_nb(void *handle, u_int32_t offset, u_int8_t val)
+{
+    return ops->writeb(handle, offset, val);
+}
+
+void
+writew_nb(void *handle, u_int32_t offset, u_int16_t val)
+{
+    return ops->writew(handle, offset, val);
+}
+
+void
+writel_nb(void *handle, u_int32_t offset, u_int32_t val)
 {
     return ops->writel(handle, offset, val);
 }
diff --git a/sys/alpha/include/bwx.h b/sys/alpha/include/bwx.h
index bbc3142d8926..3d63995d4a15 100644
--- a/sys/alpha/include/bwx.h
+++ b/sys/alpha/include/bwx.h
@@ -81,4 +81,23 @@ stl(vm_offset_t va, u_int64_t r)
     __asm__ __volatile__ ("mb");
 }
 
+static __inline void
+stb_nb(vm_offset_t va, u_int64_t r)
+{
+    __asm__ __volatile__ ("stb %1,%0" : "=m"(*(u_int8_t*)va) : "r"(r));
+}
+
+static __inline void
+stw_nb(vm_offset_t va, u_int64_t r)
+{
+    __asm__ __volatile__ ("stw %1,%0" : "=m"(*(u_int16_t*)va) : "r"(r));
+}
+
+
+static __inline void
+stl_nb(vm_offset_t va, u_int64_t r)
+{
+    __asm__ __volatile__ ("stl %1,%0" : "=m"(*(u_int32_t*)va) : "r"(r));
+}
+
 #endif /* !_MACHINE_BWX_H_ */