Bus space barriers (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 16 Jan 2015 00:12:39 +0000 (16:12 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 3 Feb 2015 15:12:28 +0000 (10:12 -0500)
On x86, a LOCK will flush the write buffers.  This is what BSD does under the
hood for their bus_space_barriers.

Technically, these are kernel headers we're messing with (the membar), but
don't worry about it.

kern/arch/riscv/ros/membar.h
kern/arch/x86/ros/membar.h
kern/drivers/net/bxe/bxe.c
kern/drivers/net/bxe/bxe.h

index 46d7860..57c462a 100644 (file)
@@ -20,4 +20,9 @@
 #define wrmb_f() wrmb()
 #define rwmb_f() rwmb()
 
+/* Bus memory barriers */
+#warning "Implement bus memory barriers"
+#define bus_wmb() mb()
+#define bus_rmb() mb()
+
 #endif /* ROS_INC_ARCH_MEMBAR_H */
index 37ed736..7ab8a90 100644 (file)
@@ -20,4 +20,8 @@
 #define wrmb_f() mb_f()
 #define rwmb_f() mb_f()
 
+/* Bus memory barriers */
+#define bus_wmb() cmb()
+#define bus_rmb() asm volatile("lock; addl $0,0(%%rsp)" : : : "memory")
+
 #endif /* ROS_INC_ARCH_MEMBAR_H */
index 0fe1716..243ff29 100644 (file)
@@ -16644,6 +16644,7 @@ bxe_igu_ack_sb(struct bxe_adapter *sc,
     bxe_igu_ack_sb_gen(sc, igu_sb_id, segment, index, op, update, igu_addr);
 }
 
+#endif
 static void
 bxe_igu_clear_sb_gen(struct bxe_adapter *sc,
                      uint8_t          func,
@@ -16709,7 +16710,6 @@ bxe_igu_clear_sb(struct bxe_adapter *sc,
 }
 
 
-#endif
 
 
 
index 6983530..d1df558 100644 (file)
@@ -68,6 +68,30 @@ typedef uint64_t uintmax_t;
 #define bus_dmamap_sync(...)
 #define bus_dmamap_unload(...)
 
+/* FreeBSD x86/include/bus.h
+ * Bus read/write barrier methods.
+ *
+ *      void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
+ *                             bus_size_t offset, bus_size_t len, int flags);
+ *
+ *
+ * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
+ * prevent reordering by the compiler; all Intel x86 processors currently
+ * retire operations outside the CPU in program order.
+ */
+#define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
+#define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
+
+static inline void
+bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
+                  bus_size_t offset, bus_size_t len, int flags)
+{
+       if (flags & BUS_SPACE_BARRIER_READ)
+               bus_rmb();
+       else
+               bus_wmb();
+}
+
 #define MA_OWNED 0
 #define mtx_assert(lock, thing) assert(1)
 #define device_printf(ignore, format, args...) printk(format, args)
@@ -2328,8 +2352,8 @@ bxe_igu_ack_sb_gen(struct bxe_adapter *sc,
     REG_WR(sc, igu_addr, cmd_data.sb_id_and_flags);
 
     /* Make sure that ACK is written */
-    //    bus_space_barrier(sc->bar[0].tag, sc->bar[0].handle, 0, 0,
-    //                BUS_SPACE_BARRIER_WRITE);
+    bus_space_barrier(sc->bar[0].tag, sc->bar[0].handle, 0, 0,
+                      BUS_SPACE_BARRIER_WRITE);
     mb();
 }
 
@@ -2355,8 +2379,8 @@ bxe_hc_ack_sb(struct bxe_adapter *sc,
     REG_WR(sc, hc_addr, (*(uint32_t *)&igu_ack));
 
     /* Make sure that ACK is written */
-    //    bus_space_barrier(sc->bar[0].tag, sc->bar[0].handle, 0, 0,
-    //                      BUS_SPACE_BARRIER_WRITE);
+    bus_space_barrier(sc->bar[0].tag, sc->bar[0].handle, 0, 0,
+                      BUS_SPACE_BARRIER_WRITE);
     mb();
 }