xref: /freebsd/share/man/man4/proto.4 (revision a90b9d0159070121c221b966469c3e36d912bf82)
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.Dd August 7, 2015
27.Dt PROTO 4
28.Os
29.\"
30.Sh NAME
31.Nm proto
32.Nd Generic prototyping and diagnostics driver
33.\"
34.Sh SYNOPSIS
35To compile this driver into the kernel,
36place the following line in your
37kernel configuration file:
38.Bd -ragged -offset indent
39.Cd "device proto"
40.Ed
41.Pp
42Alternatively, to load the driver as a
43module at boot time, place the following line in
44.Xr loader.conf 5 :
45.Bd -literal -offset indent
46proto_load="YES"
47.Ed
48.Pp
49To have the driver attach to a device instead of its regular driver,
50mention it in the list of devices assigned to the following loader variable:
51.Bd -ragged -offset indent
52hw.proto.attach="desc[,desc]"
53.Ed
54.\"
55.Sh DESCRIPTION
56The
57.Nm
58device driver attaches to PCI or ISA devices when no other device drivers
59are present for those devices and it creates device special files for all
60resources associated with the device.
61The driver itself has no knowledge of the device it attaches to.
62Programs can open these device special files and perform register-level
63reads and writes.
64As such, the
65.Nm
66device driver is nothing but a conduit or gateway between user space
67programs and the hardware device.
68.Pp
69Examples for why this is useful include hardware diagnostics and prototyping.
70In both these use cases, it is far more convenient to develop and run the
71logic in user space.
72Especially hardware diagnostics requires a somewhat user-friendly interface
73and adequate reporting.
74Neither is done easily as kernel code.
75.Ss I/O port resources
76Device special files created for I/O port resources allow
77.Xr lseek 2 ,
78.Xr read 2 ,
79.Xr write 2
80and
81.Xr ioctl 2
82operations to be performed on them.
83The
84.Xr read 2
85and
86.Xr write 2
87system calls are used to perform input and output (resp.) on the port.
88The amount of data that can be read or written at any single time is either
891, 2 or 4 bytes.
90While the
91.Nm
92driver does not prevent reading or writing 8 bytes at a time for some
93architectures, it should not be assumed that such actually produces
94correct results.
95The
96.Xr lseek 2
97system call is used to select the port number, relative to the I/O port
98region being represented by the device special file.
99If, for example, the device special file corresponds to an I/O port region
100from 0x3f8 to 0x3ff inclusive, then an offset of 4 given to lseek with a
101whence value of SEEK_SET will target port 0x3fc on the next read or write
102operation.
103The
104.Xr ioctl 2
105system call can be used for the
106.Dv PROTO_IOC_REGION
107request.
108This ioctl request returns the extend of the resource covered by this
109device special file.
110The extend is returned in the following structure:
111.Bd -literal
112struct proto_ioc_region {
113        unsigned long   address;
114        unsigned long   size;
115};
116.Ed
117.Ss Memory mapped I/O resources
118The device special files created for memory mapped I/O resources behave
119in the same way as those created for I/O port resources.
120Additionally, device special files for memory mapped I/O resources allow
121the memory to be mapped into the process' address space using
122.Xr mmap 2 .
123Reads and writes to the memory address returned by
124.Xr mmap 2
125go directly to the hardware.
126As such the use of
127.Xr read 2
128and
129.Xr write 2
130can be avoided, reducing the access overhead significantly.
131Alignment and access width constraints put forth by the underlying device
132apply.
133Also, make sure the compiler does not optimize memory accesses away or has
134them coalesced into bigger accesses.
135.Ss DMA pseudo resource
136A device special file named
137.Pa busdma
138is created for the purpose of doing DMA.
139It only supports
140.Xr ioctl 2
141and only for the
142.Dv PROTO_IOC_BUSDMA
143request.
144This device special file does not support
145.Xr read 2
146nor
147.Xr write 2 .
148The
149.Dv PROTO_IOC_BUSDMA
150request has an argument that is both in and out and is defined as
151follows:
152.Bd -literal
153struct proto_ioc_busdma {
154        unsigned int    request;
155        unsigned long   key;
156        union {
157                struct {
158                        unsigned long   align;
159                        unsigned long   bndry;
160                        unsigned long   maxaddr;
161                        unsigned long   maxsz;
162                        unsigned long   maxsegsz;
163                        unsigned int    nsegs;
164                        unsigned int    datarate;
165                        unsigned int    flags;
166                } tag;
167                struct {
168                        unsigned long   tag;
169                        unsigned int    flags;
170                        unsigned long   virt_addr;
171                        unsigned long   virt_size;
172                        unsigned int    phys_nsegs;
173                        unsigned long   phys_addr;
174                        unsigned long   bus_addr;
175                        unsigned int    bus_nsegs;
176                } md;
177                struct {
178                        unsigned int    op;
179                        unsigned long   base;
180                        unsigned long   size;
181                } sync;
182        } u;
183        unsigned long   result;
184};
185.Ed
186The
187.Va request
188field is used to specify which DMA operation is to be performed.
189The
190.Va key
191field is used to specify which object the operation applies to.
192An object is either a tag or a memory descriptor (md).
193The following DMA operations are defined:
194.Bl -tag -width XXXX
195.It PROTO_IOC_BUSDMA_TAG_CREATE
196Create a root tag.
197The
198.Va result
199field is set on output with the key of the DMA tag.
200The tag is created with the constraints given by the
201.Va tag
202sub-structure.
203These constraints correspond roughly to those that can be given to the
204.Xr bus_dma_tag_create 9
205function.
206.It PROTO_IOC_BUSDMA_TAG_DERIVE
207Create a derived tag.
208The
209.Va key
210field is used to identify the parent tag from which to derive the new tag.
211The key of the derived tag is returned in the
212.Va result
213field.
214The derived tag combines the constraints of the parent tag with those
215given by the
216.Va tag
217sub-structure.
218The combined constraints are written back to the
219.Va tag
220sub-structure on return.
221.It PROTO_IOC_BUSDMA_TAG_DESTROY
222Destroy a root or derived tag previously created.
223The
224.Va key
225field specifies the tag to destroy.
226A tag can only be destroyed when not referenced anymore.
227This means that derived tags that have this tag as a parent and memory
228descriptors created from this tag must be destroyed first.
229.It PROTO_IOC_BUSDMA_MEM_ALLOC
230Allocate memory that satisfies the constraints put forth by the tag
231given in the
232.Va tag
233field of the
234.Va md
235sub-structure.
236The key of the memory descriptor for this memory is returned in the
237.Va result
238field.
239The
240.Va md
241sub-structure is filled on return with details of the allocation.
242The kernel virtual address and the size of the allocated memory are returned
243in the
244.Va virt_addr
245and
246.Va virt_size
247fields.
248The number of contiguous physical memory segments and the address of the first
249segment are returned in the
250.Va phys_nsegs
251and
252.Va phys_addr
253fields.
254Allocated memory is automatically loaded and thus mapped into bus space.
255The number of bus segments and the address of the first segment are returned
256in the
257.Va bus_nsegs
258and
259.Va bus_addr
260fields.
261The behaviour of this operation banks heavily on how
262.Xr bus_dmamem_alloc 9
263is implemented, which means that memory is currently always allocated as a
264single contiguous region of physical memory.
265In practice this also tends to give a single contiguous region in bus space.
266This may change over time.
267.It PROTO_IOC_BUSDMA_MEM_FREE
268Free previously allocated memory and destroy the memory descriptor.
269The
270.Nm
271driver is not in a position to track whether the memory has been mapped in
272the process' address space, so the application is responsible for unmapping
273the memory before it is freed.
274The
275.Nm
276driver also cannot protect against the hardware writing to or reading from
277the memory, even after it has been freed.
278When the memory is reused for other purposes it can be corrupted or cause
279the hardware to behave in unpredictable ways when DMA has not stopped
280completely before freeing.
281.It PROTO_IOC_BUSDMA_MD_CREATE
282Create an empty memory descriptor with the tag specified in the
283.Va tag
284field of the
285.Va md
286sub-structure.
287The key of the memory descriptor is returned in the
288.Va result
289field.
290.It PROTO_IOC_BUSDMA_MD_DESTROY
291Destroy the previously created memory descriptor specified by the
292.Va key
293field.
294When the memory descriptor is still loaded, it is unloaded first.
295.It PROTO_IOC_BUSDMA_MD_LOAD
296Load a contiguous region of memory in the memory descriptor specified by the
297.Va key
298field.
299The size and address in the process' virtual address space are specified
300by the
301.Va virt_size
302and
303.Va virt_addr
304fields.
305On return, the
306.Va md
307sub-structure contains the result of the operation.
308The number of physical segments and the address of the first segment is
309returned in the
310.Va phys_nsegs
311and
312.Va phys_addr
313fields.
314The number of bus space segments and the address of the first segment in
315bus space is returned in the
316.Va bus_nsegs
317and
318.Va bus_addr
319fields.
320.It PROTO_IOC_BUSDMA_MD_UNLOAD
321Unload the memory descriptor specified by the
322.Va key
323field.
324.It PROTO_IOC_BUSDMA_SYNC
325Guarantee that all hardware components have a coherent view of the memory
326tracked by the memory descriptor, specified by the
327.Va key
328field.
329A sub-section of the memory can be targeted by specifying the relative
330offset and size of the memory to make coherent.
331The offset and size are given by the
332.Va base
333and
334.Va size
335fields of the
336.Va sync
337sub-structure.
338The
339.Va op
340field holds the sync operation to be performed.
341This is similar to the
342.Xr bus_dmamap_sync 9
343function.
344.El
345.Ss PCI configuration space
346Access to PCI configuration space is possible through the
347.Pa pcicfg
348device special file.
349The device special file supports
350.Xr lseek 2 ,
351.Xr read 2
352and
353.Xr write 2 .
354Usage is the asme as for I/O port resources.
355.Sh FILES
356All device special files corresponding to a PCI device are located under
357.Pa /dev/proto/pci<d>:<b>:<s>:<f>
358with
359.Pa pci<d>:<b>:<s>:<f>
360representing the location of the PCI device in the PCI hierarchy.
361A PCI location includes:
362.Pp
363.Bl -tag -width XXXXXX -compact -offset indent
364.It <d>
365The PCI domain number
366.It <b>
367The PCI bus number
368.It <s>
369The PCI slot or device number
370.It <f>
371The PCI function number
372.El
373.Pp
374Every PCI device has a device special file called
375.Pa pcicfg .
376This device special file gives access to the PCI configuration space.
377A device special file called
378.Pa busdma
379is also created.
380This device special file provides the interfaces needed for doing DMA.
381For each valid base address register (BAR), a device special file is created
382that contains the BAR offset and the resource type.
383A resource type can be either
384.Pa io
385or
386.Pa mem
387representing I/O port or memory mapped I/O space (resp.)
388.Pp
389ISA devices do not have a location.
390Instead, 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