xref: /freebsd/share/man/man4/proto.4 (revision 6ae1554a5d9b318f8ad53ccc39fa5a961403da73)
1.\"
2.\" Copyright (c) 2014, 2015 Marcel Moolenaar
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\"
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.\"
26.\" $FreeBSD$
27.\"
28.Dd August 7, 2015
29.Dt PROTO 4
30.Os
31.\"
32.Sh NAME
33.Nm proto
34.Nd Generic prototyping and diagnostics driver
35.\"
36.Sh SYNOPSIS
37To compile this driver into the kernel,
38place the following line in your
39kernel configuration file:
40.Bd -ragged -offset indent
41.Cd "device proto"
42.Ed
43.Pp
44Alternatively, to load the driver as a
45module at boot time, place the following line in
46.Xr loader.conf 5 :
47.Bd -literal -offset indent
48proto_load="YES"
49.Ed
50.Pp
51To have the driver attach to a device instead of its regular driver,
52mention it in the list of devices assigned to the following loader variable:
53.Bd -ragged -offset indent
54hw.proto.attach="desc[,desc]"
55.Ed
56.\"
57.Sh DESCRIPTION
58The
59.Nm
60device driver attaches to PCI or ISA devices when no other device drivers
61are present for those devices and it creates device special files for all
62resources associated with the device.
63The driver itself has no knowledge of the device it attaches to.
64Programs can open these device special files and perform register-level
65reads and writes.
66As such, the
67.Nm
68device driver is nothing but a conduit or gateway between user space
69programs and the hardware device.
70.Pp
71Examples for why this is useful include hardware diagnostics and prototyping.
72In both these use cases, it is far more convenient to develop and run the
73logic in user space.
74Especially hardware diagnostics requires a somewhat user-friendly interface
75and adequate reporting.
76Neither is done easily as kernel code.
77.Ss I/O port resources
78Device special files created for I/O port resources allow
79.Xr lseek 2 ,
80.Xr read 2 ,
81.Xr write 2
82and
83.Xr ioctl 2
84operations to be performed on them.
85The
86.Xr read 2
87and
88.Xr write 2
89system calls are used to perform input and output (resp.) on the port.
90The amount of data that can be read or written at any single time is either
911, 2 or 4 bytes.
92While the
93.Nm
94driver does not prevent reading or writing 8 bytes at a time for some
95architectures, it should not be assumed that such actually produces
96correct results.
97The
98.Xr lseek 2
99system call is used to select the port number, relative to the I/O port
100region being represented by the device special file.
101If, for example, the device special file corresponds to an I/O port region
102from 0x3f8 to 0x3ff inclusive, then an offset of 4 given to lseek with a
103whence value of SEEK_SET will target port 0x3fc on the next read or write
104operation.
105The
106.Xr ioctl 2
107system call can be used for the
108.Dv PROTO_IOC_REGION
109request.
110This ioctl request returns the extend of the resource covered by this
111device special file. The extend is returned in the following structure:
112.Bd -literal
113struct proto_ioc_region {
114        unsigned long   address;
115        unsigned long   size;
116};
117.Ed
118.Ss Memory mapped I/O resources
119The device special files created for memory mapped I/O resources behave
120in the same way as those created for I/O port resources.
121Additionally, device special files for memory mapped I/O resources allow
122the memory to be mapped into the process' address space using
123.Xr mmap 2 .
124Reads and writes to the memory address returned by
125.Xr mmap 2
126go directly to the hardware.
127As such the use of
128.Xr read 2
129and
130.Xr write 2
131can be avoided, reducing the access overhead significantly.
132Alignment and access width constraints put forth by the underlying device
133apply.
134Also, make sure the compiler does not optimize memory accesses away or has
135them coalesced into bigger accesses.
136.Ss DMA pseudo resource
137A device special file named
138.Pa busdma
139is created for the purpose of doing DMA.
140It only supports
141.Xr ioctl 2
142and only for the
143.Dv PROTO_IOC_BUSDMA
144request.
145This device special file does not support
146.Xr read 2
147nor
148.Xr write 2 .
149The
150.Dv PROTO_IOC_BUSDMA
151request has an argument that is both in and out and is defined as
152follows:
153.Bd -literal
154struct proto_ioc_busdma {
155        unsigned int    request;
156        unsigned long   key;
157        union {
158                struct {
159                        unsigned long   align;
160                        unsigned long   bndry;
161                        unsigned long   maxaddr;
162                        unsigned long   maxsz;
163                        unsigned long   maxsegsz;
164                        unsigned int    nsegs;
165                        unsigned int    datarate;
166                        unsigned int    flags;
167                } tag;
168                struct {
169                        unsigned long   tag;
170                        unsigned int    flags;
171                        unsigned long   virt_addr;
172                        unsigned long   virt_size;
173                        unsigned int    phys_nsegs;
174                        unsigned long   phys_addr;
175                        unsigned long   bus_addr;
176                        unsigned int    bus_nsegs;
177                } md;
178                struct {
179                        unsigned int    op;
180                        unsigned long   base;
181                        unsigned long   size;
182                } sync;
183        } u;
184        unsigned long   result;
185};
186.Ed
187The
188.Va request
189field is used to specify which DMA operation is to be performed.
190The
191.Va key
192field is used to specify which object the operation applies to.
193An object is either a tag or a memory descriptor (md).
194The following DMA operations are defined:
195.Bl -tag -width XXXX
196.It PROTO_IOC_BUSDMA_TAG_CREATE
197Create a root tag.
198The
199.Va result
200field is set on output with the key of the DMA tag.
201The tag is created with the constraints given by the
202.Va tag
203sub-structure. These constraints correspond roughly to those that can be
204given to the
205.Xr bus_dma_tag_create 9
206function.
207.It PROTO_IOC_BUSDMA_TAG_DERIVE
208Create a derived tag.
209The
210.Va key
211field is used to identify the parent tag from which to derive the new tag.
212The key of the derived tag is returned in the
213.Va result
214field.
215The derived tag combines the constraints of the parent tag with those
216given by the
217.Va tag
218sub-structure.
219The combined constraints are written back to the
220.Va tag
221sub-structure on return.
222.It PROTO_IOC_BUSDMA_TAG_DESTROY
223Destroy a root or derived tag previously created.
224The
225.Va key
226field specifies the tag to destroy.
227A tag can only be destroyed when not referenced anymore.
228This means that derived tags that have this tag as a parent and memory
229descriptors created from this tag must be destroyed first.
230.It PROTO_IOC_BUSDMA_MEM_ALLOC
231Allocate memory that satisfies the constraints put forth by the tag
232given in the
233.Va tag
234field of the
235.Va md
236sub-structure.
237The key of the memory descriptor for this memory is returned in the
238.Va result
239field.
240The
241.Va md
242sub-structure is filled on return with details of the allocation.
243The kernel virtual address and the size of the allocated memory are returned
244in the
245.Va virt_addr
246and
247.Va virt_size
248fields.
249The number of contigous physical memory segments and the address of the first
250segment are returned in the
251.Va phys_nsegs
252and
253.Va phys_addr
254fields.
255Allocated memory is automatically loaded and thus mapped into bus space.
256The number of bus segments and the address of the first segment are returned
257in the
258.Va bus_nsegs
259and
260.Va bus_addr
261fields.
262The behaviour of this operation banks heavily on how
263.Xr bus_dmamem_alloc 9
264is implemented, which means that memory is currently always allocated as a
265single contigous region of physical memory.
266In practice this also tends to give a single contigous region in bus space.
267This may change over time.
268.It PROTO_IOC_BUSDMA_MEM_FREE
269Free previously allocated memory and destroy the memory desciptor.
270The
271.Nm
272driver is not in a position to track whether the memory has been mapped in
273the process' address space, so the application is responsible for unmapping
274the memory before it is freed.
275The
276.Nm
277driver also cannot protect against the hardware writing to or reading from
278the memory, even after it has been freed.
279When the memory is reused for other purposes it can be corrupted or cause
280the hardware to behave in unpredictable ways when DMA has not stopped
281completely before freeing.
282.It PROTO_IOC_BUSDMA_MD_CREATE
283Create an empty memory descriptor with the tag specified in the
284.Va tag
285field of the
286.Va md
287sub-structure.
288The key of the memory descriptor is returned in the
289.Va result
290field.
291.It PROTO_IOC_BUSDMA_MD_DESTROY
292Destroy the previously created memory descriptor specified by the
293.Va key
294field.
295When the memory descriptor is still loaded, it is unloaded first.
296.It PROTO_IOC_BUSDMA_MD_LOAD
297Load a contigous region of memory in the memory descriptor specified by the
298.Va key
299field.
300The size and address in the process' virtual address space are specified
301by the
302.Va virt_size
303and
304.Va virt_addr
305fields.
306On return, the
307.Va md
308sub-structure contains the result of the operation.
309The number of physical segments and the address of the first segment is
310returned in the
311.Va phys_nsegs
312and
313.Va phys_addr
314fields.
315The number of bus space segments and the address of the first segment in
316bus space is returned in the
317.Va bus_nsegs
318and
319.Va bus_addr
320fields.
321.It PROTO_IOC_BUSDMA_MD_UNLOAD
322Unload the memory descriptor specified by the
323.Va key
324field.
325.It PROTO_IOC_BUSDMA_SYNC
326Guarantee that all hardware components have a coherent view of the memory
327tracked by the memory descriptor, specified by the
328.Va key
329field.
330A sub-section of the memory can be targeted by specifying the relative
331offset and size of the memory to make coherent.
332The offset and size are given by the
333.Va base
334and
335.Va size
336fields of the
337.Va sync
338sub-structure.
339The
340.Va op
341field holds the sync operation to be performed.
342This is similar to the
343.Xr bus_dmamap_sync 9
344function.
345.El
346.Ss PCI configuration space
347Access to PCI configuration space is possible through the
348.Pa pcicfg
349device special file.
350The device special file supports
351.Xr lseek 2 ,
352.Xr read 2
353and
354.Xr write 2 .
355Usage is the asme as for I/O port resources.
356.Sh FILES
357All device special files corresponding to a PCI device are located under
358.Pa /dev/proto/pci<d>:<b>:<s>:<f>
359with
360.Pa pci<d>:<b>:<s>:<f>
361representing the location of the PCI device in the PCI hierarchy.
362A PCI location includes:
363.Pp
364.Bl -tag -width XXXXXX -compact -offset indent
365.It <d>
366The PCI domain number
367.It <b>
368The PCI bus number
369.It <s>
370The PCI slot or device number
371.It <f>
372The PCI function number
373.El
374.Pp
375Every PCI device has a device special file called
376.Pa pcicfg .
377This device special file gives access to the PCI configuration space.
378A device special file called
379.Pa busdma
380is also created.
381This device special file provides the interfaces needed for doing DMA.
382For each valid base address register (BAR), a device special file is created
383that contains the BAR offset and the resource type.
384A resource type can be either
385.Pa io
386or
387.Pa mem
388representing I/O port or memory mapped I/O space (resp.)
389.Pp
390ISA devices do not have a location. Instead, they are identified by the
391first I/O port address or first memory mapped I/O address.
392Consequently, all device special files corresponding to an ISA device are
393located under
394.Pa /dev/proto/isa:<addr>
395with
396.Pa addr
397the address in hexadecimal notation.
398For each I/O port or memory mapped I/O address, a device special file is
399created that contains the resource identification used by the kernel and
400the resource type.
401The resource type can be either
402.Pa io
403or
404.Pa mem
405representing I/O port or memory mapped I/O space (resp.)
406When the device has a DMA channel assigned to it, a device special file
407with the name
408.Pa busdma
409is created as well.
410This device special file provides the interfaces needed for doing DMA.
411.Pp
412If the ISA device is not a Plug-and-Play device nor present in the ACPI
413device tree, it must have the appropriate hints so that the kernel can
414reserve the resources for it.
415.\"
416.Sh EXAMPLES
417A single function PCI device in domain 0, on bus 1, in slot 2 and having a
418single memory mapped I/O region will have the following device special files:
419.Pp
420.Bl -tag -width XXXXXX -compact -offset indent
421.It Pa /dev/proto/pci0:1:2:0/10.mem
422.It Pa /dev/proto/pci0:1:2:0/pcicfg
423.El
424.Pp
425A legacy floppy controller will have the following device files:
426.Pp
427.Bl -tag -width XXXXXX -compact -offset indent
428.It Pa /dev/proto/isa:0x3f0/00.io
429.It Pa /dev/proto/isa:0x3f0/01.io
430.It Pa /dev/proto/isa:0x3f0/busdma
431.El
432.\"
433.Sh SEE ALSO
434.Xr ioctl 2 ,
435.Xr lseek 2 ,
436.Xr mmap 2 ,
437.Xr read 2 ,
438.Xr write 2 ,
439.Xr bus_dma_tag_create 9 ,
440.Xr bus_dmamap_sync 9 ,
441.Xr bus_dmamem_alloc 9
442.\"
443.Sh AUTHORS
444The
445.Nm
446device driver and this manual page were written by
447.An Marcel Moolenaar Aq Mt marcel@xcllnt.net .
448.Sh SECURITY CONSIDERATIONS
449Because programs have direct access to the hardware, the
450.Nm
451driver is inherently insecure.
452It is not advisable to use this driver on a production machine.
453.\"
454.Sh MISSING FUNCTIONALITY
455The
456.Nm
457driver does not fully support memory descriptors that need multiple
458physical memory segments or multiple bus space segments.
459At the very least, an operation is needed on the DMA pseudo resource
460for the application to obtain all segments.
461.Pp
462The
463.Nm
464driver does not yet support interrupts.
465Since interrupts cannot be handled by the driver itself, they must be
466converted into signals and delivered to the program that has registered
467for interrupts.
468A satisfactory mechanism for keeping the interrupt masked during the
469signal handling is still being worked out.
470.Pp
471DMA support for devices other than busmaster devices is not present yet.
472The details of how a program is to interact with the DMA controller still
473need to be fleshed out.
474