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