Memory Barriers

Sequences of read and write instructions can often be executed more quickly if run in an order that’s different from the program text (Corbet et al., 2005). As a result, modern processors customarily reorder read and write instructions. However, this optimization can foul up drivers performing PMIO and MMIO. To prevent instruction reordering, memory barriers are employed. Memory barriers ensure that all instructions before the barrier conclude before any instruction after the barrier. For PMIO and MMIO operations, the bus_barrier function provides this ability:

#include <sys/bus.h>
#include <machine/bus.h>

void
bus_barrier(struct resource *r, bus_size_t offset, bus_size_t length,
    int flags);

The bus_barrier function inserts a memory barrier that enforces the ordering of read or write operations on a region in r, which is described by the offset and length arguments. The flags argument specifies the type of operation to be ordered. Valid values for this argument are shown in Table 10-1.

Table 10-1. bus_barrier Symbolic Constants

Constant

Description

BUS_SPACE_BARRIER_READ

Synchronizes read operations

BUS_SPACE_BARRIER_WRITE

Synchronizes write operations

Note that these flags can be ORed to enforce ordering on both read and write operations. An exemplary use of bus_barrier looks something like this:

bus_write_1(r, 0, data0);
bus_barrier(r, 0, 1, BUS_SPACE_BARRIER_WRITE);
bus_write_1(r, 0, data1);
bus_barrier(r, 0, 2, BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
data2 = bus_read_1(r, 1);
bus_barrier(r, 1, 1, BUS_SPACE_BARRIER_READ);
data3 = bus_read_1(r, 1);

Here, the calls to bus_barrier guarantee that the writes and reads conclude in the order written.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.198.146