diff options
Diffstat (limited to 'static/freebsd/man4/proto.4 3.html')
| -rw-r--r-- | static/freebsd/man4/proto.4 3.html | 349 |
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> — <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="YES"</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="desc[,desc]"</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<d>:<b>:<s>:<f></span> + with <span class="Pa">pci<d>:<b>:<s>:<f></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><d></dt> + <dd>The PCI domain number</dd> + <dt><b></dt> + <dd>The PCI bus number</dd> + <dt><s></dt> + <dd>The PCI slot or device number</dd> + <dt><f></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:<addr></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;"> </dd> + <dt><span class="Pa">/dev/proto/pci0:1:2:0/pcicfg</span></dt> + <dd style="width: auto;"> </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;"> </dd> + <dt><span class="Pa">/dev/proto/isa:0x3f0/01.io</span></dt> + <dd style="width: auto;"> </dd> + <dt><span class="Pa">/dev/proto/isa:0x3f0/busdma</span></dt> + <dd style="width: auto;"> </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> + <<a class="Mt" href="mailto:marcel@xcllnt.net">marcel@xcllnt.net</a>>.</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> |
