1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Definitions and helper macros for managing driver memory-mapped
7  * input/output (MMIO) regions appropriately in either RAM or ROM.
8  *
9  * In most cases drivers will just want to include device.h, but
10  * including this separately may be needed for arch-level driver code
11  * which uses the DEVICE_MMIO_TOPLEVEL variants and including the
12  * main device.h would introduce header dependency loops due to that
13  * header's reliance on kernel.h.
14  */
15 #ifndef ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H
16 #define ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H
17 
18 #include <zephyr/toolchain.h>
19 #include <zephyr/linker/sections.h>
20 
21 /**
22  * @defgroup device-mmio Device memory-mapped IO management
23  * @ingroup device_model
24  * @{
25  */
26 
27 /* Storing MMIO addresses in RAM is a system-wide decision based on
28  * configuration. This is just used to simplify some other definitions.
29  *
30  * If we have an MMU enabled, all physical MMIO regions must be mapped into
31  * the kernel's virtual address space at runtime, this is a hard requirement.
32  *
33  * If we have PCIE enabled, this does mean that non-PCIE drivers may waste
34  * a bit of RAM, but systems with PCI express are not RAM constrained.
35  */
36 #if defined(CONFIG_MMU) || defined(CONFIG_PCIE) || defined(CONFIG_EXTERNAL_ADDRESS_TRANSLATION)
37 #define DEVICE_MMIO_IS_IN_RAM
38 #endif
39 
40 #if defined(CONFIG_EXTERNAL_ADDRESS_TRANSLATION)
41 #include <zephyr/drivers/mm/system_mm.h>
42 #endif
43 
44 #ifndef _ASMLANGUAGE
45 #include <stdint.h>
46 #include <stddef.h>
47 #include <zephyr/sys/mem_manage.h>
48 #include <zephyr/sys/sys_io.h>
49 
50 #ifdef DEVICE_MMIO_IS_IN_RAM
51 /* Store the physical address and size from DTS, we'll memory
52  * map into the virtual address space at runtime. This is not applicable
53  * to PCIe devices, which must query the bus for BAR information.
54  */
55 struct z_device_mmio_rom {
56 	/** MMIO physical address */
57 	uintptr_t phys_addr;
58 
59 	/** MMIO region size */
60 	size_t size;
61 };
62 
63 #define Z_DEVICE_MMIO_ROM_INITIALIZER(node_id) \
64 	{ \
65 		.phys_addr = DT_REG_ADDR(node_id), \
66 		.size = DT_REG_SIZE(node_id) \
67 	}
68 
69 #define Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id) \
70 	{ \
71 		.phys_addr = DT_REG_ADDR_BY_NAME(node_id, name), \
72 		.size = DT_REG_SIZE_BY_NAME(node_id, name) \
73 	}
74 
75 /**
76  * Set linear address for device MMIO access
77  *
78  * This function sets the `virt_addr` parameter to the correct linear
79  * address for the MMIO region.
80  *
81  * If the MMU is enabled, mappings may be created in the page tables.
82  *
83  * Normally, only a caching mode needs to be set for the 'flags' parameter.
84  * The mapped linear address will have read-write access to supervisor mode.
85  *
86  * @see k_map()
87  *
88  * @param virt_addr [out] Output linear address storage location, most
89  *		users will want some DEVICE_MMIO_RAM_PTR() value
90  * @param phys_addr Physical address base of the MMIO region
91  * @param size Size of the MMIO region
92  * @param flags Caching mode and access flags, see K_MEM_CACHE_* and
93  *              K_MEM_PERM_* macros
94  */
95 __boot_func
device_map(mm_reg_t * virt_addr,uintptr_t phys_addr,size_t size,uint32_t flags)96 static inline void device_map(mm_reg_t *virt_addr, uintptr_t phys_addr,
97 			      size_t size, uint32_t flags)
98 {
99 #ifdef CONFIG_MMU
100 	/* Pass along flags and add that we want supervisor mode
101 	 * read-write access.
102 	 */
103 	z_phys_map((uint8_t **)virt_addr, phys_addr, size,
104 		   flags | K_MEM_PERM_RW);
105 #else
106 	ARG_UNUSED(size);
107 	ARG_UNUSED(flags);
108 #ifdef CONFIG_EXTERNAL_ADDRESS_TRANSLATION
109 	sys_mm_drv_page_phys_get((void *) phys_addr, virt_addr);
110 #else
111 	*virt_addr = phys_addr;
112 #endif /* CONFIG_EXTERNAL_ADDRESS_TRANSLATION */
113 #endif /* CONFIG_MMU */
114 }
115 #else
116 /* No MMU or PCIe. Just store the address from DTS and treat as a linear
117  * address
118  */
119 struct z_device_mmio_rom {
120 	/** MMIO linear address */
121 	mm_reg_t addr;
122 };
123 
124 #define Z_DEVICE_MMIO_ROM_INITIALIZER(node_id) \
125 	{ \
126 		.addr = (mm_reg_t)DT_REG_ADDR_U64(node_id) \
127 	}
128 
129 #define Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id) \
130 	{ \
131 		.addr = (mm_reg_t)DT_REG_ADDR_BY_NAME_U64(node_id, name) \
132 	}
133 
134 #endif /* DEVICE_MMIO_IS_IN_RAM */
135 #endif /* !_ASMLANGUAGE */
136 /** @} */
137 
138 /**
139  * @defgroup device-mmio-single Single MMIO region macros
140  * @ingroup device-mmio
141  *
142  * For drivers which need to manage just one MMIO region, the most common
143  * case.
144  *
145  * @{
146  */
147 
148 /**
149  * @def DEVICE_MMIO_RAM
150  *
151  * Declare storage for MMIO information within a device's dev_data struct.
152  *
153  * This gets accessed by the DEVICE_MMIO_MAP() and DEVICE_MMIO_GET() macros.
154  *
155  * Depending on configuration, no memory may be reserved at all.
156  * This must be the first member of the data struct.
157  *
158  * There must be a corresponding DEVICE_MMIO_ROM in config_info if the
159  * physical address is known at build time, but may be omitted if not (such
160  * as with PCIe)
161  *
162  * Example for a driver named "foo":
163  *
164  * struct foo_driver_data {
165  *	DEVICE_MMIO_RAM;
166  *	int wibble;
167  *	...
168  * }
169  *
170  * No build-time initialization of this memory is necessary; it
171  * will be set up in the init function by DEVICE_MMIO_MAP().
172  *
173  * A pointer to this memory may be obtained with DEVICE_MMIO_RAM_PTR().
174  */
175 #ifdef DEVICE_MMIO_IS_IN_RAM
176 #define DEVICE_MMIO_RAM			mm_reg_t _mmio
177 #else
178 #define DEVICE_MMIO_RAM
179 #endif
180 
181 #ifdef DEVICE_MMIO_IS_IN_RAM
182 /**
183  * Return a pointer to the RAM-based storage area for a device's MMIO
184  * address.
185  *
186  * This is useful for the target MMIO address location when using
187  * device_map() directly.
188  *
189  * @param device device node_id object
190  * @retval mm_reg_t  pointer to storage location
191  */
192 #define DEVICE_MMIO_RAM_PTR(device)	(mm_reg_t *)((device)->data)
193 #endif /* DEVICE_MMIO_IS_IN_RAM */
194 
195 /**
196  * @brief Declare storage for MMIO data within a device's config struct
197  *
198  * This gets accessed by DEVICE_MMIO_MAP() and DEVICE_MMIO_GET() macros.
199  *
200  * What gets stored here varies considerably by configuration.
201  * This must be the first member of the config struct. There must be
202  * a corresponding DEVICE_MMIO_RAM in data.
203  *
204  * This storage is not used if the device is PCIe and may be omitted.
205  *
206  * This should be initialized at build time with information from DTS
207  * using DEVICE_MMIO_ROM_INIT().
208  *
209  * A pointer to this memory may be obtained with DEVICE_MMIO_ROM_PTR().
210  *
211  * Example for a driver named "foo":
212  *
213  * struct foo_config {
214  *	DEVICE_MMIO_ROM;
215  *	int baz;
216  *	...
217  * }
218  *
219  * @see DEVICE_MMIO_ROM_INIT()
220  */
221 #define DEVICE_MMIO_ROM		struct z_device_mmio_rom _mmio
222 
223 /**
224  * Return a pointer to the ROM-based storage area for a device's MMIO
225  * information. This macro will not work properly if the ROM storage
226  * was omitted from the config struct declaration, and should not
227  * be used in this case.
228  *
229  * @param dev device instance object
230  * @retval struct device_mmio_rom * pointer to storage location
231  */
232 #define DEVICE_MMIO_ROM_PTR(dev) \
233 	((struct z_device_mmio_rom *)((dev)->config))
234 
235 /**
236  * @brief Initialize a DEVICE_MMIO_ROM member
237  *
238  * Initialize MMIO-related information within a specific instance of
239  * a device config struct, using information from DTS.
240  *
241  * Example for a driver belonging to the "foo" subsystem:
242  *
243  * struct foo_config my_config = {
244  *	DEVICE_MMIO_ROM_INIT(DT_DRV_INST(...)),
245  *	.baz = 2;
246  *	...
247  * }
248  *
249  * @see DEVICE_MMIO_ROM()
250  *
251  * @param node_id DTS node_id
252  */
253 #define DEVICE_MMIO_ROM_INIT(node_id) \
254 	._mmio = Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
255 
256 /**
257  * @def DEVICE_MMIO_MAP(device, flags)
258  *
259  * @brief Map MMIO memory into the address space
260  *
261  * This is not intended for PCIe devices; these must be probed at runtime
262  * and you will want to make a device_map() call directly, using
263  * DEVICE_MMIO_RAM_PTR() as the target virtual address location.
264  *
265  * The flags argument is currently used for caching mode, which should be
266  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
267  * expansion.
268  *
269  * @param dev Device object instance
270  * @param flags cache mode flags
271  */
272 #ifdef DEVICE_MMIO_IS_IN_RAM
273 #define DEVICE_MMIO_MAP(dev, flags) \
274 	device_map(DEVICE_MMIO_RAM_PTR(dev), \
275 		   DEVICE_MMIO_ROM_PTR(dev)->phys_addr, \
276 		   DEVICE_MMIO_ROM_PTR(dev)->size, \
277 		   (flags))
278 #else
279 #define DEVICE_MMIO_MAP(dev, flags) do { } while (false)
280 #endif
281 
282 /**
283  * @def DEVICE_MMIO_GET(dev)
284  *
285  * @brief Obtain the MMIO address for a device
286  *
287  * For most microcontrollers MMIO addresses can be fixed values known at
288  * build time, and we can store this in device->config, residing in ROM.
289  *
290  * However, some devices can only know their MMIO addresses at runtime,
291  * because they need to be memory-mapped into the address space, enumerated
292  * from PCI, or both.
293  *
294  * This macro returns the linear address of the driver's MMIO region.
295  * This is for drivers which have exactly one MMIO region.
296  * A call must have been made to device_map() in the driver init function.
297  *
298  * @param dev Device object
299  * @return mm_reg_t  linear address of the MMIO region
300  */
301 #ifdef DEVICE_MMIO_IS_IN_RAM
302 #define DEVICE_MMIO_GET(dev)	(*DEVICE_MMIO_RAM_PTR(dev))
303 #else
304 #define DEVICE_MMIO_GET(dev)	(DEVICE_MMIO_ROM_PTR(dev)->addr)
305 #endif
306 /** @} */
307 
308 /**
309  * @defgroup device-mmio-named Named MMIO region macros
310  * @ingroup device-mmio
311  *
312  * For drivers which need to manage multiple MMIO regions, which will
313  * be referenced by name.
314  *
315  * @{
316  */
317 
318 /**
319  * @def DEVICE_MMIO_NAMED_RAM(name)
320  *
321  * @brief Declare storage for MMIO data within a device's dev_data struct
322  *
323  * This gets accessed by the DEVICE_MMIO_NAMED_MAP() and
324  * DEVICE_MMIO_NAMED_GET() macros.
325  *
326  * Depending on configuration, no memory may be reserved at all.
327  * Multiple named regions may be declared.
328  *
329  * There must be a corresponding DEVICE_MMIO_ROM in config if the
330  * physical address is known at build time, but may be omitted if not (such
331  * as with PCIe.
332  *
333  * Example for a driver named "foo":
334  *
335  * struct foo_driver_data {
336  *      int blarg;
337  *      DEVICE_MMIO_NAMED_RAM(corge);
338  *      DEVICE_MMIO_NAMED_RAM(grault);
339  *      int wibble;
340  *      ...
341  * }
342  *
343  * No build-time initialization of this memory is necessary; it
344  * will be set up in the init function by DEVICE_MMIO_NAMED_MAP().
345  *
346  * @param name Member name to use to store within dev_data.
347  */
348 #ifdef DEVICE_MMIO_IS_IN_RAM
349 #define DEVICE_MMIO_NAMED_RAM(name)	mm_reg_t name
350 #else
351 #define DEVICE_MMIO_NAMED_RAM(name)
352 #endif /* DEVICE_MMIO_IS_IN_RAM */
353 
354 #ifdef DEVICE_MMIO_IS_IN_RAM
355 /**
356  * @brief Return a pointer to the RAM storage for a device's named MMIO address
357  *
358  * This macro requires that the macro DEV_DATA is locally defined and returns
359  * a properly typed pointer to the particular dev_data struct for this driver.
360  *
361  * @param dev device instance object
362  * @param name Member name within dev_data
363  * @retval mm_reg_t  pointer to storage location
364  */
365 #define DEVICE_MMIO_NAMED_RAM_PTR(dev, name) \
366 		(&(DEV_DATA(dev)->name))
367 #endif /* DEVICE_MMIO_IS_IN_RAM */
368 
369 /**
370  * @brief Declare storage for MMIO data within a device's config struct.
371  *
372  * This gets accessed by DEVICE_MMIO_NAMED_MAP() and
373  * DEVICE_MMIO_NAMED_GET() macros.
374  *
375  * What gets stored here varies considerably by configuration. Multiple named
376  * regions may be declared. There must be corresponding entries in the dev_data
377  * struct.
378  *
379  * This storage is not used if the device is PCIe and may be omitted.
380  *
381  * If used, this must be initialized at build time with information from DTS
382  * using DEVICE_MMIO_NAMED_ROM_INIT()
383  *
384  * A pointer to this memory may be obtained with DEVICE_MMIO_NAMED_ROM_PTR().
385  *
386  * Example for a driver named "foo":
387  *
388  * struct foo_config {
389  *      int bar;
390  *      DEVICE_MMIO_NAMED_ROM(corge);
391  *      DEVICE_MMIO_NAMED_ROM(grault);
392  *      int baz;
393  *      ...
394  * }
395  *
396  * @see DEVICE_MMIO_NAMED_ROM_INIT()
397  *
398  * @param name Member name to store within config
399  */
400 #define DEVICE_MMIO_NAMED_ROM(name) struct z_device_mmio_rom name
401 
402 /**
403  * Return a pointer to the ROM-based storage area for a device's MMIO
404  * information.
405  *
406  * This macro requires that the macro DEV_CFG is locally defined and returns
407  * a properly typed pointer to the particular config struct for this
408  * driver.
409  *
410  * @param dev device instance object
411  * @param name Member name within config
412  * @retval struct device_mmio_rom * pointer to storage location
413  */
414 #define DEVICE_MMIO_NAMED_ROM_PTR(dev, name) (&(DEV_CFG(dev)->name))
415 
416 /**
417  * @brief Initialize a named DEVICE_MMIO_NAMED_ROM member
418  *
419  * Initialize MMIO-related information within a specific instance of
420  * a device config struct, using information from DTS.
421  *
422  * Example for an instance of a driver belonging to the "foo" subsystem
423  * that will have two regions named 'corge' and 'grault':
424  *
425  * struct foo_config my_config = {
426  *	bar = 7;
427  *	DEVICE_MMIO_NAMED_ROM_INIT(corge, DT_DRV_INST(...));
428  *	DEVICE_MMIO_NAMED_ROM_INIT(grault, DT_DRV_INST(...));
429  *	baz = 2;
430  *	...
431  * }
432  *
433  * @see DEVICE_MMIO_NAMED_ROM()
434  *
435  * @param name Member name within config for the MMIO region
436  * @param node_id DTS node identifier
437  */
438 #define DEVICE_MMIO_NAMED_ROM_INIT(name, node_id) \
439 	.name = Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
440 
441 /**
442  * @brief Initialize a named DEVICE_MMIO_NAMED_ROM member using a named DT
443  *        reg property.
444  *
445  * Same as @ref DEVICE_MMIO_NAMED_ROM_INIT but the size and address are taken
446  * from a named DT reg property.
447  *
448  * Example for an instance of a driver belonging to the "foo" subsystem
449  * that will have two DT-defined regions named 'chip' and 'dale':
450  *
451  * @code{.dts}
452  *
453  *    foo@E5000000 {
454  *         reg = <0xE5000000 0x1000>, <0xE6000000 0x1000>;
455  *         reg-names = "chip", "dale";
456  *         ...
457  *    };
458  *
459  * @endcode
460  *
461  * @code{.c}
462  *
463  * struct foo_config my_config = {
464  *	bar = 7;
465  *	DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(chip, DT_DRV_INST(...));
466  *	DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(dale, DT_DRV_INST(...));
467  *	baz = 2;
468  *	...
469  * }
470  *
471  * @endcode
472  *
473  * @see DEVICE_MMIO_NAMED_ROM_INIT()
474  *
475  * @param name Member name within config for the MMIO region and name of the
476  *             reg property in the DT
477  * @param node_id DTS node identifier
478  */
479 #define DEVICE_MMIO_NAMED_ROM_INIT_BY_NAME(name, node_id) \
480 	.name = Z_DEVICE_MMIO_NAMED_ROM_INITIALIZER(name, node_id)
481 
482 /**
483  * @brief Set up memory for a named MMIO region
484  *
485  * This performs the necessary PCI probing and/or MMU virtual memory mapping
486  * such that DEVICE_MMIO_GET(name) returns a suitable linear memory address
487  * for the MMIO region.
488  *
489  * If such operations are not required by the target hardware, this expands
490  * to nothing.
491  *
492  * This should be called from the driver's init function, once for each
493  * MMIO region that needs to be mapped.
494  *
495  * This macro requires that the macros DEV_DATA and DEV_CFG are locally
496  * defined and return properly typed pointers to the particular dev_data
497  * and config structs for this driver.
498  *
499  * The flags argument is currently used for caching mode, which should be
500  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
501  * expansion.
502  *
503  * @param dev Device object
504  * @param name Member name for MMIO information, as declared with
505  *             DEVICE_MMIO_NAMED_RAM/DEVICE_MMIO_NAMED_ROM
506  * @param flags One of the DEVICE_CACHE_* caching modes
507  */
508 #ifdef DEVICE_MMIO_IS_IN_RAM
509 #define DEVICE_MMIO_NAMED_MAP(dev, name, flags) \
510 	device_map(DEVICE_MMIO_NAMED_RAM_PTR((dev), name), \
511 		   (DEVICE_MMIO_NAMED_ROM_PTR((dev), name)->phys_addr), \
512 		   (DEVICE_MMIO_NAMED_ROM_PTR((dev), name)->size), \
513 		   (flags))
514 #else
515 #define DEVICE_MMIO_NAMED_MAP(dev, name, flags) do { } while (false)
516 #endif
517 
518 /**
519  * @def DEVICE_MMIO_NAMED_GET(dev, name)
520  *
521  * @brief Obtain a named MMIO address for a device
522  *
523  * This macro returns the MMIO base address for a named region from the
524  * appropriate place within the device object's linked  data structures.
525  *
526  * This is for drivers which have multiple MMIO regions.
527  *
528  * This macro requires that the macros DEV_DATA and DEV_CFG are locally
529  * defined and return properly typed pointers to the particular dev_data
530  * and config structs for this driver.
531  *
532  * @see DEVICE_MMIO_GET
533  *
534  * @param dev Device object
535  * @param name Member name for MMIO information, as declared with
536  *             DEVICE_MMIO_NAMED_RAM/DEVICE_MMIO_NAMED_ROM
537  * @return mm_reg_t  linear address of the MMIO region
538  */
539 #ifdef DEVICE_MMIO_IS_IN_RAM
540 #define DEVICE_MMIO_NAMED_GET(dev, name) \
541 		(*DEVICE_MMIO_NAMED_RAM_PTR((dev), name))
542 #else
543 #define DEVICE_MMIO_NAMED_GET(dev, name) \
544 		((DEVICE_MMIO_NAMED_ROM_PTR((dev), name))->addr)
545 #endif /* DEVICE_MMIO_IS_IN_RAM */
546 
547 /** @} */
548 
549 /**
550  * @defgroup device-mmio-toplevel Top-level MMIO region macros
551  * @ingroup device-mmio
552  *
553  * For drivers which do not use Zephyr's driver model and do not
554  * associate struct device with a driver instance. Top-level storage
555  * is used instead, with either global or static scope.
556  *
557  * This is often useful for interrupt controller and timer drivers.
558  *
559  * Currently PCIe devices are not well-supported with this set of macros.
560  * Either use Zephyr's driver model for these kinds of devices, or
561  * manage memory manually with calls to device_map().
562  *
563  * @{
564  */
565 
566  #define Z_TOPLEVEL_ROM_NAME(name) _CONCAT(z_mmio_rom__, name)
567  #define Z_TOPLEVEL_RAM_NAME(name) _CONCAT(z_mmio_ram__, name)
568 
569 /**
570  * @def DEVICE_MMIO_TOPLEVEL(name, node_id)
571  *
572  * @brief Declare top-level storage for MMIO information, global scope
573  *
574  * This is intended for drivers which do not use Zephyr's driver model
575  * of config/dev_data linked to a struct device.
576  *
577  * Instead, this is a top-level declaration for the driver's C file.
578  * The scope of this declaration is global and may be referenced by
579  * other C files, using DEVICE_MMIO_TOPLEVEL_DECLARE.
580  *
581  * @param name Base symbol name
582  * @param node_id Device-tree node identifier for this region
583  */
584 #ifdef DEVICE_MMIO_IS_IN_RAM
585 #define DEVICE_MMIO_TOPLEVEL(name, node_id) \
586 	__pinned_bss \
587 	mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
588 	__pinned_rodata \
589 	const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
590 		Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
591 #else
592 #define DEVICE_MMIO_TOPLEVEL(name, node_id) \
593 	__pinned_rodata \
594 	const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
595 		Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
596 #endif /* DEVICE_MMIO_IS_IN_RAM */
597 
598 /**
599  * @def DEVICE_MMIO_TOPLEVEL_DECLARE(name)
600  *
601  * Provide an extern reference to a top-level MMIO region
602  *
603  * If a top-level MMIO region defined with DEVICE_MMIO_DEFINE needs to be
604  * referenced from other C files, this macro provides the necessary extern
605  * definitions.
606  *
607  * @see DEVICE_MMIO_TOPLEVEL
608  *
609  * @param name Name of the top-level MMIO region
610  */
611 
612 #ifdef DEVICE_MMIO_IS_IN_RAM
613 #define DEVICE_MMIO_TOPLEVEL_DECLARE(name) \
614 	extern mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
615 	extern const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name)
616 #else
617 #define DEVICE_MMIO_TOPLEVEL_DECLARE(name) \
618 	extern const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name)
619 #endif /* DEVICE_MMIO_IS_IN_RAM */
620 
621 /**
622  * @def  DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id)
623  *
624  * @brief Declare top-level storage for MMIO information, static scope
625  *
626  * This is intended for drivers which do not use Zephyr's driver model
627  * of config/dev_data linked to a struct device.
628  *
629  * Instead, this is a top-level declaration for the driver's C file.
630  * The scope of this declaration is static.
631  *
632  * @param name Name of the top-level MMIO region
633  * @param node_id Device-tree node identifier for this region
634  */
635 #ifdef DEVICE_MMIO_IS_IN_RAM
636 #define DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id) \
637 	__pinned_bss \
638 	static mm_reg_t Z_TOPLEVEL_RAM_NAME(name); \
639 	__pinned_rodata \
640 	static const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
641 		Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
642 #else
643 #define DEVICE_MMIO_TOPLEVEL_STATIC(name, node_id) \
644 	__pinned_rodata \
645 	static const struct z_device_mmio_rom Z_TOPLEVEL_ROM_NAME(name) = \
646 		Z_DEVICE_MMIO_ROM_INITIALIZER(node_id)
647 #endif /* DEVICE_MMIO_IS_IN_RAM */
648 
649 #ifdef DEVICE_MMIO_IS_IN_RAM
650 /**
651  * @brief Return a pointer to the RAM storage for a device's toplevel MMIO
652  * address.
653  *
654  * @param name Name of toplevel MMIO region
655  * @retval mm_reg_t  pointer to storage location
656  */
657 #define DEVICE_MMIO_TOPLEVEL_RAM_PTR(name) &Z_TOPLEVEL_RAM_NAME(name)
658 #endif /* DEVICE_MMIO_IS_IN_RAM */
659 
660 /**
661  * Return a pointer to the ROM-based storage area for a toplevel MMIO region.
662  *
663  * @param name MMIO region name
664  * @retval struct device_mmio_rom * pointer to storage location
665  */
666 #define DEVICE_MMIO_TOPLEVEL_ROM_PTR(name) &Z_TOPLEVEL_ROM_NAME(name)
667 
668 /**
669  * @def DEVICE_MMIO_TOPLEVEL_MAP(name, flags)
670  *
671  * @brief Set up memory for a driver'sMMIO region
672  *
673  * This performs the necessary MMU virtual memory mapping
674  * such that DEVICE_MMIO_GET() returns a suitable linear memory address
675  * for the MMIO region.
676  *
677  * If such operations are not required by the target hardware, this expands
678  * to nothing.
679  *
680  * This should be called once from the driver's init function.
681  *
682  * The flags argument is currently used for caching mode, which should be
683  * one of the DEVICE_CACHE_* macros. Unused bits are reserved for future
684  * expansion.
685  *
686  * @param name Name of the top-level MMIO region
687  * @param flags One of the DEVICE_CACHE_* caching modes
688  */
689 #ifdef DEVICE_MMIO_IS_IN_RAM
690 #define DEVICE_MMIO_TOPLEVEL_MAP(name, flags) \
691 	device_map(&Z_TOPLEVEL_RAM_NAME(name), \
692 		   Z_TOPLEVEL_ROM_NAME(name).phys_addr, \
693 		   Z_TOPLEVEL_ROM_NAME(name).size, flags)
694 #else
695 #define DEVICE_MMIO_TOPLEVEL_MAP(name, flags) do { } while (false)
696 #endif
697 
698 /**
699  * @def DEVICE_MMIO_TOPLEVEL_GET(name)
700  *
701  * @brief Obtain the MMIO address for a device declared top-level
702  *
703  * @see DEVICE_MMIO_GET
704  *
705  * @param name Name of the top-level MMIO region
706  * @return mm_reg_t  linear address of the MMIO region
707  */
708 #ifdef DEVICE_MMIO_IS_IN_RAM
709 #define DEVICE_MMIO_TOPLEVEL_GET(name)	\
710 		((mm_reg_t)Z_TOPLEVEL_RAM_NAME(name))
711 #else
712 #define DEVICE_MMIO_TOPLEVEL_GET(name)	\
713 		((mm_reg_t)Z_TOPLEVEL_ROM_NAME(name).addr)
714 #endif
715 /** @} */
716 
717 #endif /* ZEPHYR_INCLUDE_SYS_DEVICE_MMIO_H */
718