About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / men-chameleon-bus.txt


Based on kernel version 4.16.1. Page generated on 2018-04-09 11:53 EST.

1	=================
2	MEN Chameleon Bus
3	=================
4	
5	.. Table of Contents
6	   =================
7	   1 Introduction
8	       1.1 Scope of this Document
9	       1.2 Limitations of the current implementation
10	   2 Architecture
11	       2.1 MEN Chameleon Bus
12	       2.2 Carrier Devices
13	       2.3 Parser
14	   3 Resource handling
15	       3.1 Memory Resources
16	       3.2 IRQs
17	   4 Writing an MCB driver
18	       4.1 The driver structure
19	       4.2 Probing and attaching
20	       4.3 Initializing the driver
21	
22	
23	Introduction
24	============
25	
26	This document describes the architecture and implementation of the MEN
27	Chameleon Bus (called MCB throughout this document).
28	
29	Scope of this Document
30	----------------------
31	
32	This document is intended to be a short overview of the current
33	implementation and does by no means describe the complete possibilities of MCB
34	based devices.
35	
36	Limitations of the current implementation
37	-----------------------------------------
38	
39	The current implementation is limited to PCI and PCIe based carrier devices
40	that only use a single memory resource and share the PCI legacy IRQ.  Not
41	implemented are:
42	
43	- Multi-resource MCB devices like the VME Controller or M-Module carrier.
44	- MCB devices that need another MCB device, like SRAM for a DMA Controller's
45	  buffer descriptors or a video controller's video memory.
46	- A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
47	  per MCB device like PCIe based carriers with MSI or MSI-X support.
48	
49	Architecture
50	============
51	
52	MCB is divided into 3 functional blocks:
53	
54	- The MEN Chameleon Bus itself,
55	- drivers for MCB Carrier Devices and
56	- the parser for the Chameleon table.
57	
58	MEN Chameleon Bus
59	-----------------
60	
61	The MEN Chameleon Bus is an artificial bus system that attaches to a so
62	called Chameleon FPGA device found on some hardware produced my MEN Mikro
63	Elektronik GmbH. These devices are multi-function devices implemented in a
64	single FPGA and usually attached via some sort of PCI or PCIe link. Each
65	FPGA contains a header section describing the content of the FPGA. The
66	header lists the device id, PCI BAR, offset from the beginning of the PCI
67	BAR, size in the FPGA, interrupt number and some other properties currently
68	not handled by the MCB implementation.
69	
70	Carrier Devices
71	---------------
72	
73	A carrier device is just an abstraction for the real world physical bus the
74	Chameleon FPGA is attached to. Some IP Core drivers may need to interact with
75	properties of the carrier device (like querying the IRQ number of a PCI
76	device). To provide abstraction from the real hardware bus, an MCB carrier
77	device provides callback methods to translate the driver's MCB function calls
78	to hardware related function calls. For example a carrier device may
79	implement the get_irq() method which can be translated into a hardware bus
80	query for the IRQ number the device should use.
81	
82	Parser
83	------
84	
85	The parser reads the first 512 bytes of a Chameleon device and parses the
86	Chameleon table. Currently the parser only supports the Chameleon v2 variant
87	of the Chameleon table but can easily be adopted to support an older or
88	possible future variant. While parsing the table's entries new MCB devices
89	are allocated and their resources are assigned according to the resource
90	assignment in the Chameleon table. After resource assignment is finished, the
91	MCB devices are registered at the MCB and thus at the driver core of the
92	Linux kernel.
93	
94	Resource handling
95	=================
96	
97	The current implementation assigns exactly one memory and one IRQ resource
98	per MCB device. But this is likely going to change in the future.
99	
100	Memory Resources
101	----------------
102	
103	Each MCB device has exactly one memory resource, which can be requested from
104	the MCB bus. This memory resource is the physical address of the MCB device
105	inside the carrier and is intended to be passed to ioremap() and friends. It
106	is already requested from the kernel by calling request_mem_region().
107	
108	IRQs
109	----
110	
111	Each MCB device has exactly one IRQ resource, which can be requested from the
112	MCB bus. If a carrier device driver implements the ->get_irq() callback
113	method, the IRQ number assigned by the carrier device will be returned,
114	otherwise the IRQ number inside the Chameleon table will be returned. This
115	number is suitable to be passed to request_irq().
116	
117	Writing an MCB driver
118	=====================
119	
120	The driver structure
121	--------------------
122	
123	Each MCB driver has a structure to identify the device driver as well as
124	device ids which identify the IP Core inside the FPGA. The driver structure
125	also contains callback methods which get executed on driver probe and
126	removal from the system::
127	
128		static const struct mcb_device_id foo_ids[] = {
129			{ .device = 0x123 },
130			{ }
131		};
132		MODULE_DEVICE_TABLE(mcb, foo_ids);
133	
134		static struct mcb_driver foo_driver = {
135		driver = {
136			.name = "foo-bar",
137			.owner = THIS_MODULE,
138		},
139			.probe = foo_probe,
140			.remove = foo_remove,
141			.id_table = foo_ids,
142		};
143	
144	Probing and attaching
145	---------------------
146	
147	When a driver is loaded and the MCB devices it services are found, the MCB
148	core will call the driver's probe callback method. When the driver is removed
149	from the system, the MCB core will call the driver's remove callback method::
150	
151		static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
152		static void foo_remove(struct mcb_device *mdev);
153	
154	Initializing the driver
155	-----------------------
156	
157	When the kernel is booted or your foo driver module is inserted, you have to
158	perform driver initialization. Usually it is enough to register your driver
159	module at the MCB core::
160	
161		static int __init foo_init(void)
162		{
163			return mcb_register_driver(&foo_driver);
164		}
165		module_init(foo_init);
166	
167		static void __exit foo_exit(void)
168		{
169			mcb_unregister_driver(&foo_driver);
170		}
171		module_exit(foo_exit);
172	
173	The module_mcb_driver() macro can be used to reduce the above code::
174	
175		module_mcb_driver(foo_driver);
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog