Main index | Section 4 | Options |
Alternatively, to load the driver as a module at boot time, place the following line in loader.conf(5):
proto_load="YES"
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: hw.proto.attach="desc[,desc]"
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.
struct proto_ioc_region { unsigned long address; unsigned long size; };
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; };The request field is used to specify which DMA operation is to be performed. The key 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:
PROTO_IOC_BUSDMA_TAG_CREATE | |
Create a root tag. The result field is set on output with the key of the DMA tag. The tag is created with the constraints given by the tag sub-structure. These constraints correspond roughly to those that can be given to the bus_dma_tag_create(9) function. | |
PROTO_IOC_BUSDMA_TAG_DERIVE | |
Create a derived tag. The key 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 result field. The derived tag combines the constraints of the parent tag with those given by the tag sub-structure. The combined constraints are written back to the tag sub-structure on return. | |
PROTO_IOC_BUSDMA_TAG_DESTROY | |
Destroy a root or derived tag previously created. The key 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. | |
PROTO_IOC_BUSDMA_MEM_ALLOC | |
Allocate memory that satisfies the constraints put forth by the tag given in the tag field of the md sub-structure. The key of the memory descriptor for this memory is returned in the result field. The md 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 virt_addr and virt_size fields. The number of contigous physical memory segments and the address of the first segment are returned in the phys_nsegs and phys_addr 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 bus_nsegs and bus_addr fields. The behaviour of this operation banks heavily on how bus_dmamem_alloc(9) is implemented, which means that memory is currently always allocated as a single contigous region of physical memory. In practice this also tends to give a single contigous region in bus space. This may change over time. | |
PROTO_IOC_BUSDMA_MEM_FREE | |
Free previously allocated memory and destroy the memory descriptor. The proto 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 proto 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. | |
PROTO_IOC_BUSDMA_MD_CREATE | |
Create an empty memory descriptor with the tag specified in the tag field of the md sub-structure. The key of the memory descriptor is returned in the result field. | |
PROTO_IOC_BUSDMA_MD_DESTROY | |
Destroy the previously created memory descriptor specified by the key field. When the memory descriptor is still loaded, it is unloaded first. | |
PROTO_IOC_BUSDMA_MD_LOAD | |
Load a contigous region of memory in the memory descriptor specified by the key field. The size and address in the process' virtual address space are specified by the virt_size and virt_addr fields. On return, the md sub-structure contains the result of the operation. The number of physical segments and the address of the first segment is returned in the phys_nsegs and phys_addr fields. The number of bus space segments and the address of the first segment in bus space is returned in the bus_nsegs and bus_addr fields. | |
PROTO_IOC_BUSDMA_MD_UNLOAD | |
Unload the memory descriptor specified by the key field. | |
PROTO_IOC_BUSDMA_SYNC | |
Guarantee that all hardware components have a coherent view of the memory tracked by the memory descriptor, specified by the key 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 base and size fields of the sync sub-structure. The op field holds the sync operation to be performed. This is similar to the bus_dmamap_sync(9) function. | |
<d> | |
The PCI domain number | |
<b> | |
The PCI bus number | |
<s> | |
The PCI slot or device number | |
<f> | |
The PCI function number | |
Every PCI device has a device special file called pcicfg. This device special file gives access to the PCI configuration space. A device special file called busdma 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 io or mem representing I/O port or memory mapped I/O space (resp.)
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 /dev/proto/isa:<addr> with addr 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 io or mem 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 busdma is created as well. This device special file provides the interfaces needed for doing DMA.
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.
/dev/proto/pci0:1:2:0/10.mem
/dev/proto/pci0:1:2:0/pcicfg | |
A legacy floppy controller will have the following device files:
/dev/proto/isa:0x3f0/00.io
/dev/proto/isa:0x3f0/01.io /dev/proto/isa:0x3f0/busdma | |
The proto 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.
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.
PROTO (4) | August 7, 2015 |
Main index | Section 4 | Options |
Please direct any comments about this manual page service to Ben Bullock. Privacy policy.
“ | There are two major products of Berkeley, CA -- LSD and UNIX. We don't believe this to be strictly by coincidence. | ” |
— Jeremy S. Anderson |