Line data Source code
1 0 : /*
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 0 : #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
97 1 : 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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 */
|