xref: /freebsd/share/man/man4/proto.4 (revision c08cbc64dca550d895175d5cf9dc60d00a041415)
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.
112The extend is returned in the following structure:
113.Bd -literal
114struct proto_ioc_region {
115        unsigned long   address;
116        unsigned long   size;
117};
118.Ed
119.Ss Memory mapped I/O resources
120The device special files created for memory mapped I/O resources behave
121in the same way as those created for I/O port resources.
122Additionally, device special files for memory mapped I/O resources allow
123the memory to be mapped into the process' address space using
124.Xr mmap 2 .
125Reads and writes to the memory address returned by
126.Xr mmap 2
127go directly to the hardware.
128As such the use of
129.Xr read 2
130and
131.Xr write 2
132can be avoided, reducing the access overhead significantly.
133Alignment and access width constraints put forth by the underlying device
134apply.
135Also, make sure the compiler does not optimize memory accesses away or has
136them coalesced into bigger accesses.
137.Ss DMA pseudo resource
138A device special file named
139.Pa busdma
140is created for the purpose of doing DMA.
141It only supports
142.Xr ioctl 2
143and only for the
144.Dv PROTO_IOC_BUSDMA
145request.
146This device special file does not support
147.Xr read 2
148nor
149.Xr write 2 .
150The
151.Dv PROTO_IOC_BUSDMA
152request has an argument that is both in and out and is defined as
153follows:
154.Bd -literal
155struct proto_ioc_busdma {
156        unsigned int    request;
157        unsigned long   key;
158        union {
159                struct {
160                        unsigned long   align;
161                        unsigned long   bndry;
162                        unsigned long   maxaddr;
163                        unsigned long   maxsz;
164                        unsigned long   maxsegsz;
165                        unsigned int    nsegs;
166                        unsigned int    datarate;
167                        unsigned int    flags;
168                } tag;
169                struct {
170                        unsigned long   tag;
171                        unsigned int    flags;
172                        unsigned long   virt_addr;
173                        unsigned long   virt_size;
174                        unsigned int    phys_nsegs;
175                        unsigned long   phys_addr;
176                        unsigned long   bus_addr;
177                        unsigned int    bus_nsegs;
178                } md;
179                struct {
180                        unsigned int    op;
181                        unsigned long   base;
182                        unsigned long   size;
183                } sync;
184        } u;
185        unsigned long   result;
186};
187.Ed
188The
189.Va request
190field is used to specify which DMA operation is to be performed.
191The
192.Va key
193field is used to specify which object the operation applies to.
194An object is either a tag or a memory descriptor (md).
195The following DMA operations are defined:
196.Bl -tag -width XXXX
197.It PROTO_IOC_BUSDMA_TAG_CREATE
198Create a root tag.
199The
200.Va result
201field is set on output with the key of the DMA tag.
202The tag is created with the constraints given by the
203.Va tag
204sub-structure.
205These constraints correspond roughly to those that can be given to the
206.Xr bus_dma_tag_create 9
207function.
208.It PROTO_IOC_BUSDMA_TAG_DERIVE
209Create a derived tag.
210The
211.Va key
212field is used to identify the parent tag from which to derive the new tag.
213The key of the derived tag is returned in the
214.Va result
215field.
216The derived tag combines the constraints of the parent tag with those
217given by the
218.Va tag
219sub-structure.
220The combined constraints are written back to the
221.Va tag
222sub-structure on return.
223.It PROTO_IOC_BUSDMA_TAG_DESTROY
224Destroy a root or derived tag previously created.
225The
226.Va key
227field specifies the tag to destroy.
228A tag can only be destroyed when not referenced anymore.
229This means that derived tags that have this tag as a parent and memory
230descriptors created from this tag must be destroyed first.
231.It PROTO_IOC_BUSDMA_MEM_ALLOC
232Allocate memory that satisfies the constraints put forth by the tag
233given in the
234.Va tag
235field of the
236.Va md
237sub-structure.
238The key of the memory descriptor for this memory is returned in the
239.Va result
240field.
241The
242.Va md
243sub-structure is filled on return with details of the allocation.
244The kernel virtual address and the size of the allocated memory are returned
245in the
246.Va virt_addr
247and
248.Va virt_size
249fields.
250The number of contigous physical memory segments and the address of the first
251segment are returned in the
252.Va phys_nsegs
253and
254.Va phys_addr
255fields.
256Allocated memory is automatically loaded and thus mapped into bus space.
257The number of bus segments and the address of the first segment are returned
258in the
259.Va bus_nsegs
260and
261.Va bus_addr
262fields.
263The behaviour of this operation banks heavily on how
264.Xr bus_dmamem_alloc 9
265is implemented, which means that memory is currently always allocated as a
266single contigous region of physical memory.
267In practice this also tends to give a single contigous region in bus space.
268This may change over time.
269.It PROTO_IOC_BUSDMA_MEM_FREE
270Free previously allocated memory and destroy the memory desciptor.
271The
272.Nm
273driver is not in a position to track whether the memory has been mapped in
274the process' address space, so the application is responsible for unmapping
275the memory before it is freed.
276The
277.Nm
278driver also cannot protect against the hardware writing to or reading from
279the memory, even after it has been freed.
280When the memory is reused for other purposes it can be corrupted or cause
281the hardware to behave in unpredictable ways when DMA has not stopped
282completely before freeing.
283.It PROTO_IOC_BUSDMA_MD_CREATE
284Create an empty memory descriptor with the tag specified in the
285.Va tag
286field of the
287.Va md
288sub-structure.
289The key of the memory descriptor is returned in the
290.Va result
291field.
292.It PROTO_IOC_BUSDMA_MD_DESTROY
293Destroy the previously created memory descriptor specified by the
294.Va key
295field.
296When the memory descriptor is still loaded, it is unloaded first.
297.It PROTO_IOC_BUSDMA_MD_LOAD
298Load a contigous region of memory in the memory descriptor specified by the
299.Va key
300field.
301The size and address in the process' virtual address space are specified
302by the
303.Va virt_size
304and
305.Va virt_addr
306fields.
307On return, the
308.Va md
309sub-structure contains the result of the operation.
310The number of physical segments and the address of the first segment is
311returned in the
312.Va phys_nsegs
313and
314.Va phys_addr
315fields.
316The number of bus space segments and the address of the first segment in
317bus space is returned in the
318.Va bus_nsegs
319and
320.Va bus_addr
321fields.
322.It PROTO_IOC_BUSDMA_MD_UNLOAD
323Unload the memory descriptor specified by the
324.Va key
325field.
326.It PROTO_IOC_BUSDMA_SYNC
327Guarantee that all hardware components have a coherent view of the memory
328tracked by the memory descriptor, specified by the
329.Va key
330field.
331A sub-section of the memory can be targeted by specifying the relative
332offset and size of the memory to make coherent.
333The offset and size are given by the
334.Va base
335and
336.Va size
337fields of the
338.Va sync
339sub-structure.
340The
341.Va op
342field holds the sync operation to be performed.
343This is similar to the
344.Xr bus_dmamap_sync 9
345function.
346.El
347.Ss PCI configuration space
348Access to PCI configuration space is possible through the
349.Pa pcicfg
350device special file.
351The device special file supports
352.Xr lseek 2 ,
353.Xr read 2
354and
355.Xr write 2 .
356Usage is the asme as for I/O port resources.
357.Sh FILES
358All device special files corresponding to a PCI device are located under
359.Pa /dev/proto/pci<d>:<b>:<s>:<f>
360with
361.Pa pci<d>:<b>:<s>:<f>
362representing the location of the PCI device in the PCI hierarchy.
363A PCI location includes:
364.Pp
365.Bl -tag -width XXXXXX -compact -offset indent
366.It <d>
367The PCI domain number
368.It <b>
369The PCI bus number
370.It <s>
371The PCI slot or device number
372.It <f>
373The PCI function number
374.El
375.Pp
376Every PCI device has a device special file called
377.Pa pcicfg .
378This device special file gives access to the PCI configuration space.
379A device special file called
380.Pa busdma
381is also created.
382This device special file provides the interfaces needed for doing DMA.
383For each valid base address register (BAR), a device special file is created
384that contains the BAR offset and the resource type.
385A resource type can be either
386.Pa io
387or
388.Pa mem
389representing I/O port or memory mapped I/O space (resp.)
390.Pp
391ISA devices do not have a location.
392Instead, they are identified by the
393first I/O port address or first memory mapped I/O address.
394Consequently, all device special files corresponding to an ISA device are
395located under
396.Pa /dev/proto/isa:<addr>
397with
398.Pa addr
399the address in hexadecimal notation.
400For each I/O port or memory mapped I/O address, a device special file is
401created that contains the resource identification used by the kernel and
402the resource type.
403The resource type can be either
404.Pa io
405or
406.Pa mem
407representing I/O port or memory mapped I/O space (resp.)
408When the device has a DMA channel assigned to it, a device special file
409with the name
410.Pa busdma
411is created as well.
412This device special file provides the interfaces needed for doing DMA.
413.Pp
414If the ISA device is not a Plug-and-Play device nor present in the ACPI
415device tree, it must have the appropriate hints so that the kernel can
416reserve the resources for it.
417.\"
418.Sh EXAMPLES
419A single function PCI device in domain 0, on bus 1, in slot 2 and having a
420single memory mapped I/O region will have the following device special files:
421.Pp
422.Bl -tag -width XXXXXX -compact -offset indent
423.It Pa /dev/proto/pci0:1:2:0/10.mem
424.It Pa /dev/proto/pci0:1:2:0/pcicfg
425.El
426.Pp
427A legacy floppy controller will have the following device files:
428.Pp
429.Bl -tag -width XXXXXX -compact -offset indent
430.It Pa /dev/proto/isa:0x3f0/00.io
431.It Pa /dev/proto/isa:0x3f0/01.io
432.It Pa /dev/proto/isa:0x3f0/busdma
433.El
434.\"
435.Sh SEE ALSO
436.Xr ioctl 2 ,
437.Xr lseek 2 ,
438.Xr mmap 2 ,
439.Xr read 2 ,
440.Xr write 2 ,
441.Xr bus_dma_tag_create 9 ,
442.Xr bus_dmamap_sync 9 ,
443.Xr bus_dmamem_alloc 9
444.\"
445.Sh AUTHORS
446The
447.Nm
448device driver and this manual page were written by
449.An Marcel Moolenaar Aq Mt marcel@xcllnt.net .
450.Sh SECURITY CONSIDERATIONS
451Because programs have direct access to the hardware, the
452.Nm
453driver is inherently insecure.
454It is not advisable to use this driver on a production machine.
455.\"
456.Sh MISSING FUNCTIONALITY
457The
458.Nm
459driver does not fully support memory descriptors that need multiple
460physical memory segments or multiple bus space segments.
461At the very least, an operation is needed on the DMA pseudo resource
462for the application to obtain all segments.
463.Pp
464The
465.Nm
466driver does not yet support interrupts.
467Since interrupts cannot be handled by the driver itself, they must be
468converted into signals and delivered to the program that has registered
469for interrupts.
470A satisfactory mechanism for keeping the interrupt masked during the
471signal handling is still being worked out.
472.Pp
473DMA support for devices other than busmaster devices is not present yet.
474The details of how a program is to interact with the DMA controller still
475need to be fleshed out.
476