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