summaryrefslogtreecommitdiff
path: root/static/freebsd/man4/proto.4 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man4/proto.4 3.html')
-rw-r--r--static/freebsd/man4/proto.4 3.html349
1 files changed, 349 insertions, 0 deletions
diff --git a/static/freebsd/man4/proto.4 3.html b/static/freebsd/man4/proto.4 3.html
new file mode 100644
index 00000000..c4eb5aed
--- /dev/null
+++ b/static/freebsd/man4/proto.4 3.html
@@ -0,0 +1,349 @@
+<table class="head">
+ <tr>
+ <td class="head-ltitle">PROTO(4)</td>
+ <td class="head-vol">Device Drivers Manual</td>
+ <td class="head-rtitle">PROTO(4)</td>
+ </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<p class="Pp"><code class="Nm">proto</code> &#x2014; <span class="Nd">Generic
+ prototyping and diagnostics driver</span></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
+<p class="Pp">To compile this driver into the kernel, place the following line
+ in your kernel configuration file:</p>
+<div class="Bd Pp Bd-indent"><code class="Cd">device proto</code></div>
+<p class="Pp">Alternatively, to load the driver as a module at boot time, place
+ the following line in <a class="Xr">loader.conf(5)</a>:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>proto_load=&quot;YES&quot;</pre>
+</div>
+<p class="Pp">To have the driver attach to a device instead of its regular
+ driver, mention it in the list of devices assigned to the following loader
+ variable:</p>
+<div class="Bd Pp Bd-indent">hw.proto.attach=&quot;desc[,desc]&quot;</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+<p class="Pp">The <code class="Nm">proto</code> device driver attaches to PCI or
+ ISA devices when no other device drivers are present for those devices and
+ it creates device special files for all resources associated with the
+ device. The driver itself has no knowledge of the device it attaches to.
+ Programs can open these device special files and perform register-level
+ reads and writes. As such, the <code class="Nm">proto</code> device driver
+ is nothing but a conduit or gateway between user space programs and the
+ hardware device.</p>
+<p class="Pp">Examples for why this is useful include hardware diagnostics and
+ prototyping. In both these use cases, it is far more convenient to develop
+ and run the logic in user space. Especially hardware diagnostics requires a
+ somewhat user-friendly interface and adequate reporting. Neither is done
+ easily as kernel code.</p>
+<section class="Ss">
+<h2 class="Ss" id="I/O_port_resources"><a class="permalink" href="#I/O_port_resources">I/O
+ port resources</a></h2>
+<p class="Pp">Device special files created for I/O port resources allow
+ <a class="Xr">lseek(2)</a>, <a class="Xr">read(2)</a>,
+ <a class="Xr">write(2)</a> and <a class="Xr">ioctl(2)</a> operations to be
+ performed on them. The <a class="Xr">read(2)</a> and
+ <a class="Xr">write(2)</a> system calls are used to perform input and output
+ (resp.) on the port. The amount of data that can be read or written at any
+ single time is either 1, 2 or 4 bytes. While the
+ <code class="Nm">proto</code> driver does not prevent reading or writing 8
+ bytes at a time for some architectures, it should not be assumed that such
+ actually produces correct results. The <a class="Xr">lseek(2)</a> system
+ call is used to select the port number, relative to the I/O port region
+ being represented by the device special file. If, for example, the device
+ special file corresponds to an I/O port region from 0x3f8 to 0x3ff
+ inclusive, then an offset of 4 given to lseek with a whence value of
+ SEEK_SET will target port 0x3fc on the next read or write operation. The
+ <a class="Xr">ioctl(2)</a> system call can be used for the
+ <code class="Dv">PROTO_IOC_REGION</code> request. This ioctl request returns
+ the extend of the resource covered by this device special file. The extend
+ is returned in the following structure:</p>
+<div class="Bd Pp Li">
+<pre>struct proto_ioc_region {
+ unsigned long address;
+ unsigned long size;
+};</pre>
+</div>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Memory_mapped_I/O_resources"><a class="permalink" href="#Memory_mapped_I/O_resources">Memory
+ mapped I/O resources</a></h2>
+<p class="Pp">The device special files created for memory mapped I/O resources
+ behave in the same way as those created for I/O port resources.
+ Additionally, device special files for memory mapped I/O resources allow the
+ memory to be mapped into the process' address space using
+ <a class="Xr">mmap(2)</a>. Reads and writes to the memory address returned
+ by <a class="Xr">mmap(2)</a> go directly to the hardware. As such the use of
+ <a class="Xr">read(2)</a> and <a class="Xr">write(2)</a> can be avoided,
+ reducing the access overhead significantly. Alignment and access width
+ constraints put forth by the underlying device apply. Also, make sure the
+ compiler does not optimize memory accesses away or has them coalesced into
+ bigger accesses.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="DMA_pseudo_resource"><a class="permalink" href="#DMA_pseudo_resource">DMA
+ pseudo resource</a></h2>
+<p class="Pp">A device special file named <span class="Pa">busdma</span> is
+ created for the purpose of doing DMA. It only supports
+ <a class="Xr">ioctl(2)</a> and only for the
+ <code class="Dv">PROTO_IOC_BUSDMA</code> request. This device special file
+ does not support <a class="Xr">read(2)</a> nor <a class="Xr">write(2)</a>.
+ The <code class="Dv">PROTO_IOC_BUSDMA</code> request has an argument that is
+ both in and out and is defined as follows:</p>
+<div class="Bd Pp Li">
+<pre>struct proto_ioc_busdma {
+ unsigned int request;
+ unsigned long key;
+ union {
+ struct {
+ unsigned long align;
+ unsigned long bndry;
+ unsigned long maxaddr;
+ unsigned long maxsz;
+ unsigned long maxsegsz;
+ unsigned int nsegs;
+ unsigned int datarate;
+ unsigned int flags;
+ } tag;
+ struct {
+ unsigned long tag;
+ unsigned int flags;
+ unsigned long virt_addr;
+ unsigned long virt_size;
+ unsigned int phys_nsegs;
+ unsigned long phys_addr;
+ unsigned long bus_addr;
+ unsigned int bus_nsegs;
+ } md;
+ struct {
+ unsigned int op;
+ unsigned long base;
+ unsigned long size;
+ } sync;
+ } u;
+ unsigned long result;
+};</pre>
+</div>
+The <var class="Va">request</var> field is used to specify which DMA operation
+ is to be performed. The <var class="Va">key</var> field is used to specify
+ which object the operation applies to. An object is either a tag or a memory
+ descriptor (md). The following DMA operations are defined:
+<dl class="Bl-tag">
+ <dt>PROTO_IOC_BUSDMA_TAG_CREATE</dt>
+ <dd>Create a root tag. The <var class="Va">result</var> field is set on output
+ with the key of the DMA tag. The tag is created with the constraints given
+ by the <var class="Va">tag</var> sub-structure. These constraints
+ correspond roughly to those that can be given to the
+ <a class="Xr">bus_dma_tag_create(9)</a> function.</dd>
+ <dt>PROTO_IOC_BUSDMA_TAG_DERIVE</dt>
+ <dd>Create a derived tag. The <var class="Va">key</var> field is used to
+ identify the parent tag from which to derive the new tag. The key of the
+ derived tag is returned in the <var class="Va">result</var> field. The
+ derived tag combines the constraints of the parent tag with those given by
+ the <var class="Va">tag</var> sub-structure. The combined constraints are
+ written back to the <var class="Va">tag</var> sub-structure on
+ return.</dd>
+ <dt>PROTO_IOC_BUSDMA_TAG_DESTROY</dt>
+ <dd>Destroy a root or derived tag previously created. The
+ <var class="Va">key</var> field specifies the tag to destroy. A tag can
+ only be destroyed when not referenced anymore. This means that derived
+ tags that have this tag as a parent and memory descriptors created from
+ this tag must be destroyed first.</dd>
+ <dt>PROTO_IOC_BUSDMA_MEM_ALLOC</dt>
+ <dd>Allocate memory that satisfies the constraints put forth by the tag given
+ in the <var class="Va">tag</var> field of the <var class="Va">md</var>
+ sub-structure. The key of the memory descriptor for this memory is
+ returned in the <var class="Va">result</var> field. The
+ <var class="Va">md</var> sub-structure is filled on return with details of
+ the allocation. The kernel virtual address and the size of the allocated
+ memory are returned in the <var class="Va">virt_addr</var> and
+ <var class="Va">virt_size</var> fields. The number of contiguous physical
+ memory segments and the address of the first segment are returned in the
+ <var class="Va">phys_nsegs</var> and <var class="Va">phys_addr</var>
+ fields. Allocated memory is automatically loaded and thus mapped into bus
+ space. The number of bus segments and the address of the first segment are
+ returned in the <var class="Va">bus_nsegs</var> and
+ <var class="Va">bus_addr</var> fields. The behaviour of this operation
+ banks heavily on how <a class="Xr">bus_dmamem_alloc(9)</a> is implemented,
+ which means that memory is currently always allocated as a single
+ contiguous region of physical memory. In practice this also tends to give
+ a single contiguous region in bus space. This may change over time.</dd>
+ <dt>PROTO_IOC_BUSDMA_MEM_FREE</dt>
+ <dd>Free previously allocated memory and destroy the memory descriptor. The
+ <code class="Nm">proto</code> driver is not in a position to track whether
+ the memory has been mapped in the process' address space, so the
+ application is responsible for unmapping the memory before it is freed.
+ The <code class="Nm">proto</code> driver also cannot protect against the
+ hardware writing to or reading from the memory, even after it has been
+ freed. When the memory is reused for other purposes it can be corrupted or
+ cause the hardware to behave in unpredictable ways when DMA has not
+ stopped completely before freeing.</dd>
+ <dt>PROTO_IOC_BUSDMA_MD_CREATE</dt>
+ <dd>Create an empty memory descriptor with the tag specified in the
+ <var class="Va">tag</var> field of the <var class="Va">md</var>
+ sub-structure. The key of the memory descriptor is returned in the
+ <var class="Va">result</var> field.</dd>
+ <dt>PROTO_IOC_BUSDMA_MD_DESTROY</dt>
+ <dd>Destroy the previously created memory descriptor specified by the
+ <var class="Va">key</var> field. When the memory descriptor is still
+ loaded, it is unloaded first.</dd>
+ <dt>PROTO_IOC_BUSDMA_MD_LOAD</dt>
+ <dd>Load a contiguous region of memory in the memory descriptor specified by
+ the <var class="Va">key</var> field. The size and address in the process'
+ virtual address space are specified by the <var class="Va">virt_size</var>
+ and <var class="Va">virt_addr</var> fields. On return, the
+ <var class="Va">md</var> sub-structure contains the result of the
+ operation. The number of physical segments and the address of the first
+ segment is returned in the <var class="Va">phys_nsegs</var> and
+ <var class="Va">phys_addr</var> fields. The number of bus space segments
+ and the address of the first segment in bus space is returned in the
+ <var class="Va">bus_nsegs</var> and <var class="Va">bus_addr</var>
+ fields.</dd>
+ <dt>PROTO_IOC_BUSDMA_MD_UNLOAD</dt>
+ <dd>Unload the memory descriptor specified by the <var class="Va">key</var>
+ field.</dd>
+ <dt>PROTO_IOC_BUSDMA_SYNC</dt>
+ <dd>Guarantee that all hardware components have a coherent view of the memory
+ tracked by the memory descriptor, specified by the
+ <var class="Va">key</var> field. A sub-section of the memory can be
+ targeted by specifying the relative offset and size of the memory to make
+ coherent. The offset and size are given by the <var class="Va">base</var>
+ and <var class="Va">size</var> fields of the <var class="Va">sync</var>
+ sub-structure. The <var class="Va">op</var> field holds the sync operation
+ to be performed. This is similar to the
+ <a class="Xr">bus_dmamap_sync(9)</a> function.</dd>
+</dl>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="PCI_configuration_space"><a class="permalink" href="#PCI_configuration_space">PCI
+ configuration space</a></h2>
+<p class="Pp">Access to PCI configuration space is possible through the
+ <span class="Pa">pcicfg</span> device special file. The device special file
+ supports <a class="Xr">lseek(2)</a>, <a class="Xr">read(2)</a> and
+ <a class="Xr">write(2)</a>. Usage is the asme as for I/O port resources.</p>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="FILES"><a class="permalink" href="#FILES">FILES</a></h1>
+<p class="Pp">All device special files corresponding to a PCI device are located
+ under
+ <span class="Pa">/dev/proto/pci&lt;d&gt;:&lt;b&gt;:&lt;s&gt;:&lt;f&gt;</span>
+ with <span class="Pa">pci&lt;d&gt;:&lt;b&gt;:&lt;s&gt;:&lt;f&gt;</span>
+ representing the location of the PCI device in the PCI hierarchy. A PCI
+ location includes:</p>
+<p class="Pp"></p>
+<div class="Bd-indent">
+<dl class="Bl-tag Bl-compact">
+ <dt>&lt;d&gt;</dt>
+ <dd>The PCI domain number</dd>
+ <dt>&lt;b&gt;</dt>
+ <dd>The PCI bus number</dd>
+ <dt>&lt;s&gt;</dt>
+ <dd>The PCI slot or device number</dd>
+ <dt>&lt;f&gt;</dt>
+ <dd>The PCI function number</dd>
+</dl>
+</div>
+<p class="Pp">Every PCI device has a device special file called
+ <span class="Pa">pcicfg</span>. This device special file gives access to the
+ PCI configuration space. A device special file called
+ <span class="Pa">busdma</span> is also created. This device special file
+ provides the interfaces needed for doing DMA. For each valid base address
+ register (BAR), a device special file is created that contains the BAR
+ offset and the resource type. A resource type can be either
+ <span class="Pa">io</span> or <span class="Pa">mem</span> representing I/O
+ port or memory mapped I/O space (resp.)</p>
+<p class="Pp">ISA devices do not have a location. Instead, they are identified
+ by the first I/O port address or first memory mapped I/O address.
+ Consequently, all device special files corresponding to an ISA device are
+ located under <span class="Pa">/dev/proto/isa:&lt;addr&gt;</span> with
+ <span class="Pa">addr</span> the address in hexadecimal notation. For each
+ I/O port or memory mapped I/O address, a device special file is created that
+ contains the resource identification used by the kernel and the resource
+ type. The resource type can be either <span class="Pa">io</span> or
+ <span class="Pa">mem</span> representing I/O port or memory mapped I/O space
+ (resp.) When the device has a DMA channel assigned to it, a device special
+ file with the name <span class="Pa">busdma</span> is created as well. This
+ device special file provides the interfaces needed for doing DMA.</p>
+<p class="Pp">If the ISA device is not a Plug-and-Play device nor present in the
+ ACPI device tree, it must have the appropriate hints so that the kernel can
+ reserve the resources for it.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
+<p class="Pp">A single function PCI device in domain 0, on bus 1, in slot 2 and
+ having a single memory mapped I/O region will have the following device
+ special files:</p>
+<p class="Pp"></p>
+<div class="Bd-indent">
+<dl class="Bl-tag Bl-compact">
+ <dt><span class="Pa">/dev/proto/pci0:1:2:0/10.mem</span></dt>
+ <dd style="width: auto;">&#x00A0;</dd>
+ <dt><span class="Pa">/dev/proto/pci0:1:2:0/pcicfg</span></dt>
+ <dd style="width: auto;">&#x00A0;</dd>
+</dl>
+</div>
+<p class="Pp">A legacy floppy controller will have the following device
+ files:</p>
+<p class="Pp"></p>
+<div class="Bd-indent">
+<dl class="Bl-tag Bl-compact">
+ <dt><span class="Pa">/dev/proto/isa:0x3f0/00.io</span></dt>
+ <dd style="width: auto;">&#x00A0;</dd>
+ <dt><span class="Pa">/dev/proto/isa:0x3f0/01.io</span></dt>
+ <dd style="width: auto;">&#x00A0;</dd>
+ <dt><span class="Pa">/dev/proto/isa:0x3f0/busdma</span></dt>
+ <dd style="width: auto;">&#x00A0;</dd>
+</dl>
+</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+ ALSO</a></h1>
+<p class="Pp"><a class="Xr">ioctl(2)</a>, <a class="Xr">lseek(2)</a>,
+ <a class="Xr">mmap(2)</a>, <a class="Xr">read(2)</a>,
+ <a class="Xr">write(2)</a>, <a class="Xr">bus_dma_tag_create(9)</a>,
+ <a class="Xr">bus_dmamap_sync(9)</a>,
+ <a class="Xr">bus_dmamem_alloc(9)</a></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
+<p class="Pp">The <code class="Nm">proto</code> device driver and this manual
+ page were written by <span class="An">Marcel Moolenaar</span>
+ &lt;<a class="Mt" href="mailto:marcel@xcllnt.net">marcel@xcllnt.net</a>&gt;.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SECURITY_CONSIDERATIONS"><a class="permalink" href="#SECURITY_CONSIDERATIONS">SECURITY
+ CONSIDERATIONS</a></h1>
+<p class="Pp">Because programs have direct access to the hardware, the
+ <code class="Nm">proto</code> driver is inherently insecure. It is not
+ advisable to use this driver on a production machine.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="MISSING_FUNCTIONALITY"><a class="permalink" href="#MISSING_FUNCTIONALITY">MISSING
+ FUNCTIONALITY</a></h1>
+<p class="Pp">The <code class="Nm">proto</code> driver does not fully support
+ memory descriptors that need multiple physical memory segments or multiple
+ bus space segments. At the very least, an operation is needed on the DMA
+ pseudo resource for the application to obtain all segments.</p>
+<p class="Pp">The <code class="Nm">proto</code> driver does not yet support
+ interrupts. Since interrupts cannot be handled by the driver itself, they
+ must be converted into signals and delivered to the program that has
+ registered for interrupts. A satisfactory mechanism for keeping the
+ interrupt masked during the signal handling is still being worked out.</p>
+<p class="Pp">DMA support for devices other than busmaster devices is not
+ present yet. The details of how a program is to interact with the DMA
+ controller still need to be fleshed out.</p>
+</section>
+</div>
+<table class="foot">
+ <tr>
+ <td class="foot-date">August 7, 2015</td>
+ <td class="foot-os">FreeBSD 15.0</td>
+ </tr>
+</table>